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