]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | 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 |