Line data Source code
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 : 20 : #ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED 21 : #define BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED 22 : 23 : #include <cstring> 24 : #include <string> 25 : #include <boost/iostreams/detail/config/wide_streams.hpp> 26 : #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS 27 : # include <cwchar> 28 : #endif 29 : #include <boost/static_assert.hpp> 30 : #include <boost/type.hpp> 31 : #include <boost/type_traits/is_same.hpp> 32 : 33 : namespace boost { namespace iostreams { namespace detail { 34 : 35 : #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //------------------------------------// 36 : 37 : class path { 38 : template<typename T, typename V> 39 : struct sfinae 40 : { 41 : typedef V type; 42 : }; 43 : public: 44 : 45 : // Default constructor 46 : path() : narrow_(), wide_(), is_wide_(false) { } 47 : 48 : // Constructor taking a std::string 49 0 : path(const std::string& p) : narrow_(p), wide_(), is_wide_(false) { } 50 : 51 : // Constructor taking a C-style string 52 : path(const char* p) : narrow_(p), wide_(), is_wide_(false) { } 53 : 54 : // Constructor taking a boost::filesystem2::path or 55 : // boost::filesystem2::wpath 56 : template<typename Path> 57 : explicit path(const Path& p, typename Path::external_string_type* = 0) 58 : { 59 : init(p.external_file_string()); 60 : } 61 : 62 : // Constructor taking a boost::filesystem3::path (boost filesystem v3) 63 : template<typename Path> 64 : explicit path(const Path& p, typename Path::codecvt_type* = 0) 65 : { 66 : init(p.native()); 67 : } 68 : 69 : // Copy constructor 70 : path(const path& p) 71 : : narrow_(p.narrow_), wide_(p.wide_), is_wide_(p.is_wide_) 72 : { } 73 : 74 : // Assignment operator taking another path 75 : path& operator=(const path& p) 76 : { 77 : narrow_ = p.narrow_; 78 : wide_ = p.wide_; 79 : is_wide_ = p.is_wide_; 80 : return *this; 81 : } 82 : 83 : // Assignment operator taking a std::string 84 : path& operator=(const std::string& p) 85 : { 86 : narrow_ = p; 87 : wide_.clear(); 88 : is_wide_ = false; 89 : return *this; 90 : } 91 : 92 : // Assignment operator taking a C-style string 93 : path& operator=(const char* p) 94 : { 95 : narrow_.assign(p); 96 : wide_.clear(); 97 : is_wide_ = false; 98 : return *this; 99 : } 100 : 101 : #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) 102 : // Assignment operator taking a boost::filesystem2::path or 103 : // boost::filesystem2::wpath 104 : // (not on Visual C++ 7.1/8.0, as it seems to have problems with 105 : // SFINAE functions with the same parameters, doesn't seem 106 : // worth working around). 107 : template<typename Path> 108 : typename sfinae<typename Path::external_string_type, path&>::type 109 : operator=(const Path& p) 110 : { 111 : init(p.external_file_string()); 112 : return *this; 113 : } 114 : #endif 115 : 116 : // Assignment operator taking a boost::filesystem3::path 117 : template<typename Path> 118 : typename sfinae<typename Path::codecvt_type, path&>::type 119 : operator=(const Path& p) 120 : { 121 : init(p.native()); 122 : return *this; 123 : } 124 : 125 : bool is_wide() const { return is_wide_; } 126 : 127 : // Returns a representation of the underlying path as a std::string 128 : // Requires: is_wide() returns false 129 : const char* c_str() const { return narrow_.c_str(); } 130 : 131 : // Returns a representation of the underlying path as a std::wstring 132 : // Requires: is_wide() returns true 133 : const wchar_t* c_wstr() const { return wide_.c_str(); } 134 : private: 135 : 136 : // For wide-character paths, use a boost::filesystem::wpath instead of a 137 : // std::wstring 138 : path(const std::wstring&); 139 : path& operator=(const std::wstring&); 140 : 141 : void init(std::string const& file_path) 142 : { 143 : narrow_ = file_path; 144 : wide_.clear(); 145 : is_wide_ = false; 146 : } 147 : 148 : void init(std::wstring const& file_path) 149 : { 150 : narrow_.clear(); 151 : wide_ = file_path; 152 : is_wide_ = true; 153 : } 154 : 155 : std::string narrow_; 156 : std::wstring wide_; 157 : bool is_wide_; 158 : }; 159 : 160 : inline bool operator==(const path& lhs, const path& rhs) 161 : { 162 : return lhs.is_wide() ? 163 : rhs.is_wide() && std::wcscmp(lhs.c_wstr(), rhs.c_wstr()) == 0 : 164 : !rhs.is_wide() && std::strcmp(lhs.c_str(), rhs.c_str()) == 0; 165 : } 166 : 167 : #else // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //---------------------------// 168 : 169 : class path { 170 : public: 171 : path() { } 172 : path(const std::string& p) : path_(p) { } 173 : path(const char* p) : path_(p) { } 174 : template<typename Path> 175 : path(const Path& p) : path_(p.external_file_string()) { } 176 : path(const path& p) : path_(p.path_) { } 177 : path& operator=(const path& other) 178 : { 179 : path_ = other.path_; 180 : return *this; 181 : } 182 : path& operator=(const std::string& p) 183 : { 184 : path_ = p; 185 : return *this; 186 : } 187 : path& operator=(const char* p) 188 : { 189 : path_ = p; 190 : return *this; 191 : } 192 : template<typename Path> 193 : path& operator=(const Path& p) 194 : { 195 : path_ = p.external_file_string(); 196 : return *this; 197 : } 198 : bool is_wide() const { return false; } 199 : const char* c_str() const { return path_.c_str(); } 200 : const wchar_t* c_wstr() const { return 0; } 201 : private: 202 : std::string path_; 203 : }; 204 : 205 : inline bool operator==(const path& lhs, const path& rhs) 206 : { 207 : return std::strcmp(lhs.c_str(), rhs.c_str()) == 0 ; 208 : } 209 : 210 : #endif // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //--------------------------// 211 : 212 : } } } // End namespaces detail, iostreams, boost. 213 : 214 : #endif // #ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED