blob: 34e13a9c6a60274069b4b6bc6c9561c4166c1bdf [file] [log] [blame]
Jeff Thompson86b6d642013-10-17 15:01:56 -07001// filesystem path_traits.hpp --------------------------------------------------------//
2
3// Copyright Beman Dawes 2009
4
5// Distributed under the Boost Software License, Version 1.0.
6// See http://www.boost.org/LICENSE_1_0.txt
7
8// Library home page: http://www.boost.org/libs/filesystem
9
10#ifndef NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP
11#define NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP
12
13#include <ndnboost/config.hpp>
14
15# if defined( NDNBOOST_NO_STD_WSTRING )
16# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
17# endif
18
19#include <ndnboost/filesystem/config.hpp>
20#include <ndnboost/utility/enable_if.hpp>
21#include <ndnboost/type_traits/is_array.hpp>
22#include <ndnboost/type_traits/decay.hpp>
23#include <ndnboost/system/error_code.hpp>
24#include <cwchar> // for mbstate_t
25#include <string>
26#include <vector>
27#include <list>
28#include <iterator>
29#include <locale>
30#include <ndnboost/assert.hpp>
31// #include <iostream> //**** comment me out ****
32
33#include <ndnboost/config/abi_prefix.hpp> // must be the last #include
34
35namespace ndnboost { namespace filesystem {
36
37 NDNBOOST_FILESYSTEM_DECL const system::error_category& codecvt_error_category();
38 // uses std::codecvt_base::result used for error codes:
39 //
40 // ok: Conversion successful.
41 // partial: Not all source characters converted; one or more additional source
42 // characters are needed to produce the final target character, or the
43 // size of the target intermediate buffer was too small to hold the result.
44 // error: A character in the source could not be converted to the target encoding.
45 // noconv: The source and target characters have the same type and encoding, so no
46 // conversion was necessary.
47
48 class directory_entry;
49
50namespace path_traits {
51
52 typedef std::codecvt<wchar_t, char, std::mbstate_t> codecvt_type;
53
54 // is_pathable type trait; allows disabling over-agressive class path member templates
55
56 template <class T>
57 struct is_pathable { static const bool value = false; };
58
59 template<> struct is_pathable<char*> { static const bool value = true; };
60 template<> struct is_pathable<const char*> { static const bool value = true; };
61 template<> struct is_pathable<wchar_t*> { static const bool value = true; };
62 template<> struct is_pathable<const wchar_t*> { static const bool value = true; };
63 template<> struct is_pathable<std::string> { static const bool value = true; };
64 template<> struct is_pathable<std::wstring> { static const bool value = true; };
65 template<> struct is_pathable<std::vector<char> > { static const bool value = true; };
66 template<> struct is_pathable<std::vector<wchar_t> > { static const bool value = true; };
67 template<> struct is_pathable<std::list<char> > { static const bool value = true; };
68 template<> struct is_pathable<std::list<wchar_t> > { static const bool value = true; };
69 template<> struct is_pathable<directory_entry> { static const bool value = true; };
70
71 // Pathable empty
72
73 template <class Container> inline
74 // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
75 // conforming compilers. Replace by plain "bool" at some future date (2012?)
76 typename ndnboost::disable_if<ndnboost::is_array<Container>, bool>::type
77 empty(const Container & c)
78 { return c.begin() == c.end(); }
79
80 template <class T> inline
81 bool empty(T * const & c_str)
82 {
83 NDNBOOST_ASSERT(c_str);
84 return !*c_str;
85 }
86
87 template <typename T, size_t N> inline
88 bool empty(T (&x)[N])
89 { return !x[0]; }
90
91 // value types differ ---------------------------------------------------------------//
92 //
93 // A from_end argument of 0 is less efficient than a known end, so use only if needed
94
95 NDNBOOST_FILESYSTEM_DECL
96 void convert(const char* from,
97 const char* from_end, // 0 for null terminated MBCS
98 std::wstring & to,
99 const codecvt_type& cvt);
100
101 NDNBOOST_FILESYSTEM_DECL
102 void convert(const wchar_t* from,
103 const wchar_t* from_end, // 0 for null terminated MBCS
104 std::string & to,
105 const codecvt_type& cvt);
106
107 inline
108 void convert(const char* from,
109 std::wstring & to,
110 const codecvt_type& cvt)
111 {
112 NDNBOOST_ASSERT(from);
113 convert(from, 0, to, cvt);
114 }
115
116 inline
117 void convert(const wchar_t* from,
118 std::string & to,
119 const codecvt_type& cvt)
120 {
121 NDNBOOST_ASSERT(from);
122 convert(from, 0, to, cvt);
123 }
124
125 // value types same -----------------------------------------------------------------//
126
127 // char
128
129 inline
130 void convert(const char* from, const char* from_end, std::string & to,
131 const codecvt_type&)
132 {
133 NDNBOOST_ASSERT(from);
134 NDNBOOST_ASSERT(from_end);
135 to.append(from, from_end);
136 }
137
138 inline
139 void convert(const char* from,
140 std::string & to,
141 const codecvt_type&)
142 {
143 NDNBOOST_ASSERT(from);
144 to += from;
145 }
146
147 // wchar_t
148
149 inline
150 void convert(const wchar_t* from, const wchar_t* from_end, std::wstring & to,
151 const codecvt_type&)
152 {
153 NDNBOOST_ASSERT(from);
154 NDNBOOST_ASSERT(from_end);
155 to.append(from, from_end);
156 }
157
158 inline
159 void convert(const wchar_t* from,
160 std::wstring & to,
161 const codecvt_type&)
162 {
163 NDNBOOST_ASSERT(from);
164 to += from;
165 }
166
167 // Source dispatch -----------------------------------------------------------------//
168
169 // contiguous containers
170 template <class U> inline
171 void dispatch(const std::string& c, U& to, const codecvt_type& cvt)
172 {
173 if (c.size())
174 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
175 }
176 template <class U> inline
177 void dispatch(const std::wstring& c, U& to, const codecvt_type& cvt)
178 {
179 if (c.size())
180 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
181 }
182 template <class U> inline
183 void dispatch(const std::vector<char>& c, U& to, const codecvt_type& cvt)
184 {
185 if (c.size())
186 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
187 }
188 template <class U> inline
189 void dispatch(const std::vector<wchar_t>& c, U& to, const codecvt_type& cvt)
190 {
191 if (c.size())
192 convert(&*c.begin(), &*c.begin() + c.size(), to, cvt);
193 }
194
195 // non-contiguous containers
196 template <class Container, class U> inline
197 // disable_if aids broken compilers (IBM, old GCC, etc.) and is harmless for
198 // conforming compilers. Replace by plain "void" at some future date (2012?)
199 typename ndnboost::disable_if<ndnboost::is_array<Container>, void>::type
200 dispatch(const Container & c, U& to, const codecvt_type& cvt)
201 {
202 if (c.size())
203 {
204 std::basic_string<typename Container::value_type> s(c.begin(), c.end());
205 convert(s.c_str(), s.c_str()+s.size(), to, cvt);
206 }
207 }
208
209 // c_str
210 template <class T, class U> inline
211 void dispatch(T * const & c_str, U& to, const codecvt_type& cvt)
212 {
213// std::cout << "dispatch() const T *\n";
214 NDNBOOST_ASSERT(c_str);
215 convert(c_str, to, cvt);
216 }
217
218 // Note: there is no dispatch on C-style arrays because the array may
219 // contain a string smaller than the array size.
220
221 NDNBOOST_FILESYSTEM_DECL
222 void dispatch(const directory_entry & de,
223# ifdef NDNBOOST_WINDOWS_API
224 std::wstring & to,
225# else
226 std::string & to,
227# endif
228 const codecvt_type&);
229
230
231}}} // namespace ndnboost::filesystem::path_traits
232
233#include <ndnboost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
234
235#endif // NDNBOOST_FILESYSTEM_PATH_TRAITS_HPP