Boost logo

Boost-Commit :

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;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk