path.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Distributed under the Boost Software License, Version 1.0.(See accompanying
  3. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
  4. *
  5. * See http://www.boost.org/libs/iostreams for documentation.
  6. *
  7. * File: boost/iostreams/detail/path.hpp
  8. * Date: Sat Jun 21 21:24:05 MDT 2008
  9. * Copyright: 2008 CodeRage, LLC
  10. * Author: Jonathan Turkanis
  11. * Contact: turkanis at coderage dot com
  12. *
  13. * Defines the class boost::iostreams::detail::path, for storing a
  14. * a std::string or std::wstring.
  15. *
  16. * This class allows interoperability with Boost.Filesystem without
  17. * creating a dependence on Boost.Filesystem headers or implementation.
  18. */
  19. #ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED
  20. #define BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED
  21. #include <cstring>
  22. #include <string>
  23. #include <boost/iostreams/detail/config/wide_streams.hpp>
  24. #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
  25. # include <cwchar>
  26. #endif
  27. #include <boost/static_assert.hpp>
  28. #include <boost/type.hpp>
  29. #include <boost/type_traits/is_same.hpp>
  30. namespace boost { namespace iostreams { namespace detail {
  31. #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //------------------------------------//
  32. class path {
  33. template<typename T, typename V>
  34. struct sfinae
  35. {
  36. typedef V type;
  37. };
  38. public:
  39. // Default constructor
  40. path() : narrow_(), wide_(), is_wide_(false) { }
  41. // Constructor taking a std::string
  42. path(const std::string& p) : narrow_(p), wide_(), is_wide_(false) { }
  43. // Constructor taking a C-style string
  44. path(const char* p) : narrow_(p), wide_(), is_wide_(false) { }
  45. // Constructor taking a boost::filesystem2::path or
  46. // boost::filesystem2::wpath
  47. template<typename Path>
  48. explicit path(const Path& p, typename Path::external_string_type* = 0)
  49. {
  50. init(p.external_file_string());
  51. }
  52. // Constructor taking a boost::filesystem3::path (boost filesystem v3)
  53. template<typename Path>
  54. explicit path(const Path& p, typename Path::codecvt_type* = 0)
  55. {
  56. init(p.native());
  57. }
  58. // Copy constructor
  59. path(const path& p)
  60. : narrow_(p.narrow_), wide_(p.wide_), is_wide_(p.is_wide_)
  61. { }
  62. // Assignment operator taking another path
  63. path& operator=(const path& p)
  64. {
  65. narrow_ = p.narrow_;
  66. wide_ = p.wide_;
  67. is_wide_ = p.is_wide_;
  68. return *this;
  69. }
  70. // Assignment operator taking a std::string
  71. path& operator=(const std::string& p)
  72. {
  73. narrow_ = p;
  74. wide_.clear();
  75. is_wide_ = false;
  76. return *this;
  77. }
  78. // Assignment operator taking a C-style string
  79. path& operator=(const char* p)
  80. {
  81. narrow_.assign(p);
  82. wide_.clear();
  83. is_wide_ = false;
  84. return *this;
  85. }
  86. #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
  87. // Assignment operator taking a boost::filesystem2::path or
  88. // boost::filesystem2::wpath
  89. // (not on Visual C++ 7.1/8.0, as it seems to have problems with
  90. // SFINAE functions with the same parameters, doesn't seem
  91. // worth working around).
  92. template<typename Path>
  93. typename sfinae<typename Path::external_string_type, path&>::type
  94. operator=(const Path& p)
  95. {
  96. init(p.external_file_string());
  97. return *this;
  98. }
  99. #endif
  100. // Assignment operator taking a boost::filesystem3::path
  101. template<typename Path>
  102. typename sfinae<typename Path::codecvt_type, path&>::type
  103. operator=(const Path& p)
  104. {
  105. init(p.native());
  106. return *this;
  107. }
  108. bool is_wide() const { return is_wide_; }
  109. // Returns a representation of the underlying path as a std::string
  110. // Requires: is_wide() returns false
  111. const char* c_str() const { return narrow_.c_str(); }
  112. // Returns a representation of the underlying path as a std::wstring
  113. // Requires: is_wide() returns true
  114. const wchar_t* c_wstr() const { return wide_.c_str(); }
  115. private:
  116. // For wide-character paths, use a boost::filesystem::wpath instead of a
  117. // std::wstring
  118. path(const std::wstring&);
  119. path& operator=(const std::wstring&);
  120. void init(std::string const& file_path)
  121. {
  122. narrow_ = file_path;
  123. wide_.clear();
  124. is_wide_ = false;
  125. }
  126. void init(std::wstring const& file_path)
  127. {
  128. narrow_.clear();
  129. wide_ = file_path;
  130. is_wide_ = true;
  131. }
  132. std::string narrow_;
  133. std::wstring wide_;
  134. bool is_wide_;
  135. };
  136. inline bool operator==(const path& lhs, const path& rhs)
  137. {
  138. return lhs.is_wide() ?
  139. rhs.is_wide() && std::wcscmp(lhs.c_wstr(), rhs.c_wstr()) == 0 :
  140. !rhs.is_wide() && std::strcmp(lhs.c_str(), rhs.c_str()) == 0;
  141. }
  142. #else // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //---------------------------//
  143. class path {
  144. public:
  145. path() { }
  146. path(const std::string& p) : path_(p) { }
  147. path(const char* p) : path_(p) { }
  148. template<typename Path>
  149. path(const Path& p) : path_(p.external_file_string()) { }
  150. path(const path& p) : path_(p.path_) { }
  151. path& operator=(const path& other)
  152. {
  153. path_ = other.path_;
  154. return *this;
  155. }
  156. path& operator=(const std::string& p)
  157. {
  158. path_ = p;
  159. return *this;
  160. }
  161. path& operator=(const char* p)
  162. {
  163. path_ = p;
  164. return *this;
  165. }
  166. template<typename Path>
  167. path& operator=(const Path& p)
  168. {
  169. path_ = p.external_file_string();
  170. return *this;
  171. }
  172. bool is_wide() const { return false; }
  173. const char* c_str() const { return path_.c_str(); }
  174. const wchar_t* c_wstr() const { return 0; }
  175. private:
  176. std::string path_;
  177. };
  178. inline bool operator==(const path& lhs, const path& rhs)
  179. {
  180. return std::strcmp(lhs.c_str(), rhs.c_str()) == 0 ;
  181. }
  182. #endif // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //--------------------------//
  183. } } } // End namespaces detail, iostreams, boost.
  184. #endif // #ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED