$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r76541 - in trunk: boost/filesystem/v3 libs/filesystem/v3/src libs/filesystem/v3/test libs/filesystem/v3/test/msvc10
From: bdawes_at_[hidden]
Date: 2012-01-16 10:59:29
Author: bemandawes
Date: 2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
New Revision: 76541
URL: http://svn.boost.org/trac/boost/changeset/76541
Log:
Add test cases and fixes for class path errors when assignment or appends used self or portion of self as source. Fixes ticket #3714 
Text files modified: 
   trunk/boost/filesystem/v3/path.hpp                     |    48 ++++++++++++++++++++++++++++----------  
   trunk/boost/filesystem/v3/path_traits.hpp              |     2                                         
   trunk/libs/filesystem/v3/src/path.cpp                  |    39 ++++++++++++++++++++++++++++---         
   trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln |     6 ++++                                    
   trunk/libs/filesystem/v3/test/path_test.cpp            |    49 ++++++++++++++++++++++++++++++++++++++++
   5 files changed, 126 insertions(+), 18 deletions(-)
Modified: trunk/boost/filesystem/v3/path.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path.hpp	(original)
+++ trunk/boost/filesystem/v3/path.hpp	2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -183,6 +183,12 @@
       return *this;
     }
 
+    path& operator=(const value_type* ptr)  // required in case ptr overlaps *this
+    {
+      m_pathname = ptr;
+      return *this;
+    }
+
     template <class Source>
       typename boost::enable_if<path_traits::is_pathable<
         typename boost::decay<Source>::type>, path&>::type
@@ -193,6 +199,12 @@
       return *this;
     }
 
+    path& assign(const value_type* ptr, const codecvt_type&)  // required in case ptr overlaps *this
+    {
+      m_pathname = ptr;
+      return *this;
+    }
+
     template <class Source>
     path& assign(Source const& source, const codecvt_type& cvt)
     {
@@ -227,6 +239,8 @@
 
     path& operator/=(const path& p);
 
+    path& operator/=(const value_type* ptr);
+
     template <class Source>
       typename boost::enable_if<path_traits::is_pathable<
         typename boost::decay<Source>::type>, path&>::type
@@ -235,6 +249,12 @@
       return append(source, codecvt());
     }
 
+    path& append(const value_type* ptr, const codecvt_type&)  // required in case ptr overlaps *this
+    {
+      this->operator/=(ptr);
+      return *this;
+    }
+
     template <class Source>
     path& append(Source const& source, const codecvt_type& cvt);
 
@@ -378,6 +398,16 @@
     }
     bool is_relative() const         { return !is_absolute(); } 
 
+    //  -----  iterators  -----
+
+    class iterator;
+    typedef iterator const_iterator;
+
+    iterator begin() const;
+    iterator end() const;
+
+    //  -----  static members  -----
+
     //  -----  imbue  -----
 
     static std::locale imbue(const std::locale& loc);
@@ -389,14 +419,6 @@
       return *wchar_t_codecvt_facet();
     }
 
-    //  -----  iterators  -----
-
-    class iterator;
-    typedef iterator const_iterator;
-
-    iterator begin() const;
-    iterator end() const;
-
     //  -----  deprecated functions  -----
 
 # if defined(BOOST_FILESYSTEM_DEPRECATED) && defined(BOOST_FILESYSTEM_NO_DEPRECATED)
@@ -650,14 +672,14 @@
   }
 
   template <class Source>
-  path& path::append(Source const & source, const codecvt_type& cvt)
+  path& path::append(Source const& source, const codecvt_type& cvt)
   {
     if (path_traits::empty(source))
       return *this;
-    string_type::size_type sep_pos(m_append_separator_if_needed());
-    path_traits::dispatch(source, m_pathname, cvt);
-    if (sep_pos)
-      m_erase_redundant_separator(sep_pos);
+      string_type::size_type sep_pos(m_append_separator_if_needed());
+      path_traits::dispatch(source, m_pathname, cvt);
+      if (sep_pos)
+        m_erase_redundant_separator(sep_pos);
     return *this;
   }
 
Modified: trunk/boost/filesystem/v3/path_traits.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path_traits.hpp	(original)
+++ trunk/boost/filesystem/v3/path_traits.hpp	2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -164,7 +164,7 @@
     to += from;
   }
 
-  //  Source dispatch
+  //  Source dispatch  -----------------------------------------------------------------//
 
   //  contiguous containers
   template <class U> inline
Modified: trunk/libs/filesystem/v3/src/path.cpp
==============================================================================
--- trunk/libs/filesystem/v3/src/path.cpp	(original)
+++ trunk/libs/filesystem/v3/src/path.cpp	2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -145,13 +145,44 @@
 namespace filesystem3
 {
 
-  path & path::operator/=(const path & p)
+  path& path::operator/=(const path& p)
   {
     if (p.empty())
       return *this;
-    if (!is_separator(*p.m_pathname.begin()))
-      m_append_separator_if_needed();
-    m_pathname += p.m_pathname;
+    if (this == &p)  // self-append
+    {
+      path rhs(p);
+      if (!is_separator(rhs.m_pathname[0]))
+        m_append_separator_if_needed();
+      m_pathname += rhs.m_pathname;
+    }
+    else
+    {
+      if (!is_separator(*p.m_pathname.begin()))
+        m_append_separator_if_needed();
+      m_pathname += p.m_pathname;
+    }
+    return *this;
+  }
+
+  path& path::operator/=(const value_type* ptr)
+  {
+    if (!*ptr)
+      return *this;
+    if (ptr >= m_pathname.data()
+      && ptr < m_pathname.data() + m_pathname.size())  // overlapping source
+    {
+      path rhs(ptr);
+      if (!is_separator(rhs.m_pathname[0]))
+        m_append_separator_if_needed();
+      m_pathname += rhs.m_pathname;
+    }
+    else
+    {
+      if (!is_separator(*ptr))
+        m_append_separator_if_needed();
+      m_pathname += ptr;
+    }
     return *this;
   }
 
Modified: trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln
==============================================================================
--- trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln	(original)
+++ trunk/libs/filesystem/v3/test/msvc10/filesystem-v3.sln	2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -79,6 +79,8 @@
                 {FFD738F7-96F0-445C-81EA-551665EF53D1} = {FFD738F7-96F0-445C-81EA-551665EF53D1}
         EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "thread_test", "thread_test\thread_test.vcxproj", "{20E2805D-9634-46CE-B979-21CCBBD16EA3}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -177,6 +179,10 @@
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Debug|Win32.Build.0 = Debug|Win32
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.ActiveCfg = Release|Win32
                 {B1FA4137-7B08-4113-9EC0-F3BAFEFBE2B7}.Release|Win32.Build.0 = Release|Win32
+		{20E2805D-9634-46CE-B979-21CCBBD16EA3}.Debug|Win32.ActiveCfg = Debug|Win32
+		{20E2805D-9634-46CE-B979-21CCBBD16EA3}.Debug|Win32.Build.0 = Debug|Win32
+		{20E2805D-9634-46CE-B979-21CCBBD16EA3}.Release|Win32.ActiveCfg = Release|Win32
+		{20E2805D-9634-46CE-B979-21CCBBD16EA3}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE
Modified: trunk/libs/filesystem/v3/test/path_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/path_test.cpp	(original)
+++ trunk/libs/filesystem/v3/test/path_test.cpp	2012-01-16 10:59:27 EST (Mon, 16 Jan 2012)
@@ -57,6 +57,12 @@
 #include <boost/detail/lightweight_test.hpp>
 #include <boost/detail/lightweight_main.hpp>
 
+#ifdef BOOST_WINDOWS_API
+# define BOOST_DIR_SEP "\\"
+#else
+# define BOOST_DIR_SEP "/"
+#endif
+
 #define PATH_CHECK(a, b) check(a, b, __FILE__, __LINE__)
 #define CHECK_EQUAL(a,b) check_equal(a, b, __FILE__, __LINE__)
 
@@ -1520,6 +1526,48 @@
 
   }
 
+//  self_assign_and_append_tests  ------------------------------------------------------//
+
+  void self_assign_and_append_tests()
+  {
+    std::cout << "self_assign_and_append_tests..." << std::endl;
+
+    path p;
+
+    p = "snafubar";
+    BOOST_TEST_EQ(p = p, "snafubar");
+
+    p = "snafubar";
+    p = p.c_str();
+    BOOST_TEST_EQ(p, "snafubar");
+
+    p = "snafubar";
+    p.assign(p.c_str(), path::codecvt());
+    BOOST_TEST_EQ(p, "snafubar");  
+
+    p = "snafubar";
+    BOOST_TEST_EQ(p = p.c_str()+5, "bar");
+
+    p = "snafubar";
+    BOOST_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
+
+    p = "snafubar";
+    p /= p;
+    BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
+
+    p = "snafubar";
+    p /= p.c_str();
+    BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");  
+
+    p = "snafubar";
+    p.append(p.c_str(), path::codecvt());
+    BOOST_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar"); 
+
+    p = "snafubar";
+    BOOST_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
+  }
+
+
   //  name_function_tests  -------------------------------------------------------------//
 
   void name_function_tests()
@@ -1678,6 +1726,7 @@
 
   construction_tests();
   append_tests();
+  self_assign_and_append_tests();
   overload_tests();
   query_and_decomposition_tests();
   composition_tests();