summaryrefslogtreecommitdiff
path: root/boost/filesystem/path.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/filesystem/path.hpp')
-rw-r--r--boost/filesystem/path.hpp208
1 files changed, 160 insertions, 48 deletions
diff --git a/boost/filesystem/path.hpp b/boost/filesystem/path.hpp
index 2dd1b00ea5..37f39d0a3b 100644
--- a/boost/filesystem/path.hpp
+++ b/boost/filesystem/path.hpp
@@ -121,9 +121,10 @@ namespace filesystem
// multi-byte character strings which may have embedded nulls. Embedded null
// support is required for some Asian languages on Windows.
- // [defaults] "const codecvt_type& cvt=codecvt()" default arguments are not used
- // because some compilers, such as Microsoft prior to VC++ 10, do not handle defaults
- // correctly in templates.
+ // "const codecvt_type& cvt=codecvt()" default arguments are not used because this
+ // limits the impact of locale("") initialization failures on POSIX systems to programs
+ // that actually depend on locale(""). It further ensures that exceptions thrown
+ // as a result of such failues occur after main() has started, so can be caught.
// ----- constructors -----
@@ -136,23 +137,16 @@ namespace filesystem
typename boost::enable_if<path_traits::is_pathable<
typename boost::decay<Source>::type> >::type* =0)
{
- path_traits::dispatch(source, m_pathname, codecvt());
+ path_traits::dispatch(source, m_pathname);
}
- // Overloads for the operating system API's native character type. Rationale:
- // - Avoids use of codecvt() for native value_type strings. This limits the
- // impact of locale("") initialization failures on POSIX systems to programs
- // that actually depend on locale(""). It further ensures that exceptions thrown
- // as a result of such failues occur after main() has started, so can be caught.
- // This is a partial resolution of tickets 4688, 5100, and 5289.
- // - A slight optimization for a common use case, particularly on POSIX since
- // value_type is char and that is the most common useage.
path(const value_type* s) : m_pathname(s) {}
- path(const std::basic_string<value_type>& s) : m_pathname(s) {}
+ path(value_type* s) : m_pathname(s) {}
+ path(const string_type& s) : m_pathname(s) {}
+ path(string_type& s) : m_pathname(s) {}
template <class Source>
path(Source const& source, const codecvt_type& cvt)
- // see [defaults] note above explaining why codecvt() default arguments are not used
{
path_traits::dispatch(source, m_pathname, cvt);
}
@@ -162,9 +156,10 @@ namespace filesystem
{
if (begin != end)
{
+ // convert requires contiguous string, so copy
std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
s(begin, end);
- path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, codecvt());
+ path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname);
}
}
@@ -173,6 +168,7 @@ namespace filesystem
{
if (begin != end)
{
+ // convert requires contiguous string, so copy
std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
s(begin, end);
path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname, cvt);
@@ -187,28 +183,27 @@ namespace filesystem
return *this;
}
- path& operator=(const value_type* ptr) // required in case ptr overlaps *this
- {
- m_pathname = ptr;
- return *this;
- }
-
template <class Source>
typename boost::enable_if<path_traits::is_pathable<
typename boost::decay<Source>::type>, path&>::type
operator=(Source const& source)
{
m_pathname.clear();
- path_traits::dispatch(source, m_pathname, codecvt());
+ path_traits::dispatch(source, m_pathname);
return *this;
}
- path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
- {
- m_pathname = ptr;
- return *this;
- }
+ // value_type overloads
+ path& operator=(const value_type* ptr) // required in case ptr overlaps *this
+ {m_pathname = ptr; return *this;}
+ path& operator=(value_type* ptr) // required in case ptr overlaps *this
+ {m_pathname = ptr; return *this;}
+ path& operator=(const string_type& s) {m_pathname = s; return *this;}
+ path& operator=(string_type& s) {m_pathname = s; return *this;}
+
+ path& assign(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
+ {m_pathname = ptr; return *this;}
template <class Source>
path& assign(Source const& source, const codecvt_type& cvt)
{
@@ -220,7 +215,14 @@ namespace filesystem
template <class InputIterator>
path& assign(InputIterator begin, InputIterator end)
{
- return assign(begin, end, codecvt());
+ m_pathname.clear();
+ if (begin != end)
+ {
+ std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+ s(begin, end);
+ path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname);
+ }
+ return *this;
}
template <class InputIterator>
@@ -238,19 +240,22 @@ namespace filesystem
// ----- concatenation -----
- path& operator+=(const path& p) {m_pathname += p.m_pathname; return *this;}
- path& operator+=(const string_type& s) {m_pathname += s; return *this;}
- path& operator+=(const value_type* ptr) {m_pathname += ptr; return *this;}
- path& operator+=(value_type c) {m_pathname += c; return *this;}
-
template <class Source>
typename boost::enable_if<path_traits::is_pathable<
typename boost::decay<Source>::type>, path&>::type
operator+=(Source const& source)
{
- return concat(source, codecvt());
+ return concat(source);
}
+ // value_type overloads. Same rationale as for constructors above
+ path& operator+=(const path& p) { m_pathname += p.m_pathname; return *this; }
+ path& operator+=(const value_type* ptr) { m_pathname += ptr; return *this; }
+ path& operator+=(value_type* ptr) { m_pathname += ptr; return *this; }
+ path& operator+=(const string_type& s) { m_pathname += s; return *this; }
+ path& operator+=(string_type& s) { m_pathname += s; return *this; }
+ path& operator+=(value_type c) { m_pathname += c; return *this; }
+
template <class CharT>
typename boost::enable_if<is_integral<CharT>, path&>::type
operator+=(CharT c)
@@ -258,7 +263,14 @@ namespace filesystem
CharT tmp[2];
tmp[0] = c;
tmp[1] = 0;
- return concat(tmp, codecvt());
+ return concat(tmp);
+ }
+
+ template <class Source>
+ path& concat(Source const& source)
+ {
+ path_traits::dispatch(source, m_pathname);
+ return *this;
}
template <class Source>
@@ -271,7 +283,12 @@ namespace filesystem
template <class InputIterator>
path& concat(InputIterator begin, InputIterator end)
{
- return concat(begin, end, codecvt());
+ if (begin == end)
+ return *this;
+ std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+ s(begin, end);
+ path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname);
+ return *this;
}
template <class InputIterator>
@@ -292,14 +309,26 @@ namespace filesystem
path& operator/=(const path& p);
- path& operator/=(const value_type* ptr);
-
template <class Source>
typename boost::enable_if<path_traits::is_pathable<
typename boost::decay<Source>::type>, path&>::type
operator/=(Source const& source)
{
- return append(source, codecvt());
+ return append(source);
+ }
+
+ path& operator/=(const value_type* ptr);
+ path& operator/=(value_type* ptr)
+ {
+ return this->operator/=(const_cast<const value_type*>(ptr));
+ }
+ path& operator/=(const string_type& s) { return this->operator/=(path(s)); }
+ path& operator/=(string_type& s) { return this->operator/=(path(s)); }
+
+ path& append(const value_type* ptr) // required in case ptr overlaps *this
+ {
+ this->operator/=(ptr);
+ return *this;
}
path& append(const value_type* ptr, const codecvt_type&) // required in case ptr overlaps *this
@@ -309,13 +338,13 @@ namespace filesystem
}
template <class Source>
+ path& append(Source const& source);
+
+ template <class Source>
path& append(Source const& source, const codecvt_type& cvt);
template <class InputIterator>
- path& append(InputIterator begin, InputIterator end)
- {
- return append(begin, end, codecvt());
- }
+ path& append(InputIterator begin, InputIterator end);
template <class InputIterator>
path& append(InputIterator begin, InputIterator end, const codecvt_type& cvt);
@@ -364,7 +393,14 @@ namespace filesystem
String string(const codecvt_type& cvt) const;
# ifdef BOOST_WINDOWS_API
- const std::string string() const { return string(codecvt()); }
+ const std::string string() const
+ {
+ std::string tmp;
+ if (!m_pathname.empty())
+ path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
+ tmp);
+ return tmp;
+ }
const std::string string(const codecvt_type& cvt) const
{
std::string tmp;
@@ -383,7 +419,14 @@ namespace filesystem
const std::string& string() const { return m_pathname; }
const std::string& string(const codecvt_type&) const { return m_pathname; }
- const std::wstring wstring() const { return wstring(codecvt()); }
+ const std::wstring wstring() const
+ {
+ std::wstring tmp;
+ if (!m_pathname.empty())
+ path_traits::convert(&*m_pathname.begin(), &*m_pathname.begin()+m_pathname.size(),
+ tmp);
+ return tmp;
+ }
const std::wstring wstring(const codecvt_type& cvt) const
{
std::wstring tmp;
@@ -404,7 +447,7 @@ namespace filesystem
String generic_string(const codecvt_type& cvt) const;
# ifdef BOOST_WINDOWS_API
- const std::string generic_string() const { return generic_string(codecvt()); }
+ const std::string generic_string() const;
const std::string generic_string(const codecvt_type& cvt) const;
const std::wstring generic_wstring() const;
const std::wstring generic_wstring(const codecvt_type&) const { return generic_wstring(); };
@@ -413,7 +456,7 @@ namespace filesystem
// On POSIX-like systems, the generic format is the same as the native format
const std::string& generic_string() const { return m_pathname; }
const std::string& generic_string(const codecvt_type&) const { return m_pathname; }
- const std::wstring generic_wstring() const { return wstring(codecvt()); }
+ const std::wstring generic_wstring() const { return wstring(); }
const std::wstring generic_wstring(const codecvt_type& cvt) const { return wstring(cvt); }
# endif
@@ -556,6 +599,10 @@ namespace filesystem
BOOST_FILESYSTEM_DECL
int lex_compare(path::iterator first1, path::iterator last1,
path::iterator first2, path::iterator last2);
+ BOOST_FILESYSTEM_DECL
+ const path& dot_path();
+ BOOST_FILESYSTEM_DECL
+ const path& dot_dot_path();
}
# ifndef BOOST_FILESYSTEM_NO_DEPRECATED
@@ -686,8 +733,22 @@ namespace filesystem
//--------------------------------------------------------------------------------------//
template <class InputIterator>
+ path& path::append(InputIterator begin, InputIterator end)
+ {
+ if (begin == end)
+ return *this;
+ string_type::size_type sep_pos(m_append_separator_if_needed());
+ std::basic_string<typename std::iterator_traits<InputIterator>::value_type>
+ s(begin, end);
+ path_traits::convert(s.c_str(), s.c_str()+s.size(), m_pathname);
+ if (sep_pos)
+ m_erase_redundant_separator(sep_pos);
+ return *this;
+ }
+
+ template <class InputIterator>
path& path::append(InputIterator begin, InputIterator end, const codecvt_type& cvt)
- {
+ {
if (begin == end)
return *this;
string_type::size_type sep_pos(m_append_separator_if_needed());
@@ -700,6 +761,18 @@ namespace filesystem
}
template <class Source>
+ path& path::append(Source const& source)
+ {
+ if (path_traits::empty(source))
+ return *this;
+ string_type::size_type sep_pos(m_append_separator_if_needed());
+ path_traits::dispatch(source, m_pathname);
+ if (sep_pos)
+ m_erase_redundant_separator(sep_pos);
+ return *this;
+ }
+
+ template <class Source>
path& path::append(Source const& source, const codecvt_type& cvt)
{
if (path_traits::empty(source))
@@ -747,7 +820,46 @@ namespace filesystem
std::wstring path::generic_string<std::wstring>(const codecvt_type& cvt) const
{ return generic_wstring(cvt); }
+ //--------------------------------------------------------------------------------------//
+ // path_traits convert function implementations //
+ // requiring path::codecvt() be visable //
+ //--------------------------------------------------------------------------------------//
+
+namespace path_traits
+{ // without codecvt
+ inline
+ void convert(const char* from,
+ const char* from_end, // 0 for null terminated MBCS
+ std::wstring & to)
+ {
+ convert(from, from_end, to, path::codecvt());
+ }
+
+ inline
+ void convert(const wchar_t* from,
+ const wchar_t* from_end, // 0 for null terminated MBCS
+ std::string & to)
+ {
+ convert(from, from_end, to, path::codecvt());
+ }
+
+ inline
+ void convert(const char* from,
+ std::wstring & to)
+ {
+ BOOST_ASSERT(from);
+ convert(from, 0, to, path::codecvt());
+ }
+
+ inline
+ void convert(const wchar_t* from,
+ std::string & to)
+ {
+ BOOST_ASSERT(from);
+ convert(from, 0, to, path::codecvt());
+ }
+} // namespace path_traits
} // namespace filesystem
} // namespace boost