$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r64986 - in trunk: boost/filesystem/v3 libs/filesystem/v3/test
From: bdawes_at_[hidden]
Date: 2010-08-24 14:35:44
Author: bemandawes
Date: 2010-08-24 14:35:41 EDT (Tue, 24 Aug 2010)
New Revision: 64986
URL: http://svn.boost.org/trac/boost/changeset/64986
Log:
Add path_traits::is_pathable and use it to prevent several path member templates from being considered for overload resolution of non-pathable types. Fixes problem reported by Adam Badura.
Text files modified: 
   trunk/boost/filesystem/v3/path.hpp               |    12 +++++++++---                            
   trunk/boost/filesystem/v3/path_traits.hpp        |    19 +++++++++++++++++++                     
   trunk/libs/filesystem/v3/test/path_unit_test.cpp |    10 ++++++++++                              
   3 files changed, 38 insertions(+), 3 deletions(-)
Modified: trunk/boost/filesystem/v3/path.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path.hpp	(original)
+++ trunk/boost/filesystem/v3/path.hpp	2010-08-24 14:35:41 EDT (Tue, 24 Aug 2010)
@@ -127,7 +127,9 @@
     path(const path& p) : m_pathname(p.m_pathname) {}
  
     template <class Source>
-    path(Source const& source)
+    path(Source const& source,
+      typename boost::enable_if<path_traits::is_pathable<
+        typename boost::decay<Source>::type> >::type* =0)
     {
       path_traits::dispatch(source, m_pathname, codecvt());
     }
@@ -170,7 +172,9 @@
     }
 
     template <class Source>
-    path& operator=(Source const& source)
+      typename boost::enable_if<path_traits::is_pathable<
+        typename boost::decay<Source>::type>, path&>::type
+    operator=(Source const& source)
     {
       m_pathname.clear();
       path_traits::dispatch(source, m_pathname, codecvt());
@@ -212,7 +216,9 @@
     path& operator/=(const path& p);
 
     template <class Source>
-    path& operator/=(Source const& source)
+      typename boost::enable_if<path_traits::is_pathable<
+        typename boost::decay<Source>::type>, path&>::type
+    operator/=(Source const& source)
     {
       return append(source, codecvt());
     }
Modified: trunk/boost/filesystem/v3/path_traits.hpp
==============================================================================
--- trunk/boost/filesystem/v3/path_traits.hpp	(original)
+++ trunk/boost/filesystem/v3/path_traits.hpp	2010-08-24 14:35:41 EDT (Tue, 24 Aug 2010)
@@ -19,10 +19,12 @@
 #include <boost/filesystem/v3/config.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/decay.hpp>
 #include <boost/system/error_code.hpp>
 #include <cwchar>  // for mbstate_t
 #include <string>
 #include <vector>
+#include <list>
 #include <iterator>
 #include <locale>
 #include <boost/assert.hpp>
@@ -49,6 +51,23 @@
  
   typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
 
+  //  is_pathable type trait; allows disabling over-agressive class path member templates
+
+  template <class T>
+  struct is_pathable { static const bool value = false; };
+
+  template<> struct is_pathable<char*>                  { static const bool value = true; };
+  template<> struct is_pathable<const char*>            { static const bool value = true; };
+  template<> struct is_pathable<wchar_t*>               { static const bool value = true; };
+  template<> struct is_pathable<const wchar_t*>         { static const bool value = true; };
+  template<> struct is_pathable<std::string>            { static const bool value = true; };
+  template<> struct is_pathable<std::wstring>           { static const bool value = true; };
+  template<> struct is_pathable<std::vector<char> >     { static const bool value = true; };
+  template<> struct is_pathable<std::vector<wchar_t> >  { static const bool value = true; };
+  template<> struct is_pathable<std::list<char> >       { static const bool value = true; };
+  template<> struct is_pathable<std::list<wchar_t> >    { static const bool value = true; };
+  template<> struct is_pathable<directory_entry>        { static const bool value = true; };
+
   //  Pathable empty
 
   template <class Container> inline
Modified: trunk/libs/filesystem/v3/test/path_unit_test.cpp
==============================================================================
--- trunk/libs/filesystem/v3/test/path_unit_test.cpp	(original)
+++ trunk/libs/filesystem/v3/test/path_unit_test.cpp	2010-08-24 14:35:41 EDT (Tue, 24 Aug 2010)
@@ -41,6 +41,7 @@
 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp>  // for imbue tests
 #include "test_codecvt.hpp"                                // for codecvt arg tests
 #include <boost/detail/lightweight_test.hpp>
+#include <boost/smart_ptr.hpp>  // used constructor tests
 
 #include <iostream>
 #include <iomanip>
@@ -146,6 +147,11 @@
   std::vector<char> v;      // see main() for initialization to f, u, z
   std::vector<wchar_t> wv;  // see main() for initialization to w, f, u, z
 
+  class Base {};
+  class Derived : public Base {};
+  void fun(const boost::filesystem::path&) {}
+  void fun(const boost::shared_ptr< Base >&) {}
+
   //  test_constructors  ---------------------------------------------------------------//
 
   void test_constructors()
@@ -224,6 +230,10 @@
 
     // easy-to-make coding errors
     // path e1(x0, path::codecvt());  // fails to compile, and that is OK
+
+    boost::shared_ptr< Derived > pDerived( new Derived() ); 
+    fun( pDerived );  // tests constructor member template enable_if working correctly;
+                      // will fail to compile if enable_if not taking path off the table
   }
 
   path x;