Files
filesystem/v3/test/path_unit_test.cpp

918 lines
27 KiB
C++

// filesystem path_unit_test.cpp --------------------------------------------------- //
// Copyright Beman Dawes 2008, 2009
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// Library home page: http://www.boost.org/libs/filesystem
// ---------------------------------------------------------------------------------- //
//
// The purpose of this test is to ensure that each function in the public
// interface can be called with arguments of the appropriate types. It does
// not attempt to verify that the full range of values for each argument
// are processed correctly.
//
// For full functionality tests, including probes with many different argument
// values, see path_test.cpp and other test programs.
//
// ---------------------------------------------------------------------------------- //
#define BOOST_FILESYSTEM_VERSION 3
#include <boost/config/warning_disable.hpp>
// See deprecated_test for tests of deprecated features
#define BOOST_FILESYSTEM_NO_DEPRECATED
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp> // for imbue tests
#include <boost/detail/lightweight_test.hpp>
#include <iostream>
#include <sstream>
#include <string>
#include <locale>
#include <list>
namespace fs = boost::filesystem;
namespace bs = boost::system;
using boost::filesystem::path;
using std::cout;
using std::endl;
using std::string;
using std::wstring;
#define CHECK(x) check(x, __FILE__, __LINE__)
#define PATH_IS(a, b) check_path(a, b, __FILE__, __LINE__)
#define IS(a,b) check_equal(a, b, __FILE__, __LINE__)
#if defined(_MSC_VER)
# pragma warning(push) // Save warning settings.
# pragma warning(disable : 4428) // Disable universal-character-name encountered in source warning.
#endif
namespace
{
boost::system::error_code ec;
const boost::system::error_code ok;
const boost::system::error_code ng(-1, boost::system::system_category());
std::string platform(BOOST_PLATFORM);
void check_path(const path & source,
const wstring & expected, const char* file, int line)
{
if (source == expected) return;
++::boost::detail::test_errors();
std::cout << file;
std::wcout << L'(' << line << L"): source.wstring(): \""
<< source.wstring()
<< L"\" != expected: \"" << expected
<< L"\"\n" ;
}
template< class T1, class T2 >
void check_equal(const T1 & value,
const T2 & expected, const char* file, int line)
{
if (value == expected) return;
++::boost::detail::test_errors();
std::cout << file;
std::wcout << L'(' << line << L"): value: \"" << value
<< L"\" != expected: \"" << expected
<< L"\"\n" ;
}
void check(bool ok, const char* file, int line)
{
if (ok) return;
++::boost::detail::test_errors();
std::cout << file << '(' << line << "): test failed\n";
}
string s("string");
wstring ws(L"wstring");
std::list<char> l; // see main() for initialization to s, t, r, i, n, g
std::list<wchar_t> wl; // see main() for initialization to w, s, t, r, i, n, g
std::vector<char> v; // see main() for initialization to f, u, z
std::vector<wchar_t> wv; // see main() for initialization to w, f, u, z
// test_constructors ---------------------------------------------------------------//
void test_constructors()
{
std::cout << "testing constructors..." << std::endl;
path x0; // default constructor
PATH_IS(x0, L"");
BOOST_TEST_EQ(x0.native().size(), 0U);
path x1(l.begin(), l.end()); // iterator range char
PATH_IS(x1, L"string");
BOOST_TEST_EQ(x1.native().size(), 6U);
path x2(x1); // copy constructor
PATH_IS(x2, L"string");
BOOST_TEST_EQ(x2.native().size(), 6U);
path x3(wl.begin(), wl.end()); // iterator range wchar_t
PATH_IS(x3, L"wstring");
BOOST_TEST_EQ(x3.native().size(), 7U);
// contiguous containers
path x4(string("std::string")); // std::string
PATH_IS(x4, L"std::string");
BOOST_TEST_EQ(x4.native().size(), 11U);
path x5(wstring(L"std::wstring")); // std::wstring
PATH_IS(x5, L"std::wstring");
BOOST_TEST_EQ(x5.native().size(), 12U);
path x4v(v); // std::vector<char>
PATH_IS(x4v, L"fuz");
BOOST_TEST_EQ(x4v.native().size(), 3U);
path x5v(wv); // std::vector<wchar_t>
PATH_IS(x5v, L"wfuz");
BOOST_TEST_EQ(x5v.native().size(), 4U);
path x6("array char"); // array char
PATH_IS(x6, L"array char");
BOOST_TEST_EQ(x6.native().size(), 10U);
path x7(L"array wchar_t"); // array wchar_t
PATH_IS(x7, L"array wchar_t");
BOOST_TEST_EQ(x7.native().size(), 13U);
path x8(s.c_str()); // const char* null terminated
PATH_IS(x8, L"string");
BOOST_TEST_EQ(x8.native().size(), 6U);
path x9(ws.c_str()); // const wchar_t* null terminated
PATH_IS(x9, L"wstring");
BOOST_TEST_EQ(x9.native().size(), 7U);
// non-contiguous containers
path x10(l); // std::list<char>
PATH_IS(x10, L"string");
BOOST_TEST_EQ(x10.native().size(), 6U);
path xll(wl); // std::list<wchar_t>
PATH_IS(xll, L"wstring");
BOOST_TEST_EQ(xll.native().size(), 7U);
}
path x;
path y;
// test_assignments ----------------------------------------------------------------//
void test_assignments()
{
std::cout << "testing assignments..." << std::endl;
x = path("yet another path"); // another path
PATH_IS(x, L"yet another path");
BOOST_TEST_EQ(x.native().size(), 16U);
x = x; // self-assignment
PATH_IS(x, L"yet another path");
BOOST_TEST_EQ(x.native().size(), 16U);
x.assign(l.begin(), l.end()); // iterator range char
PATH_IS(x, L"string");
x.assign(wl.begin(), wl.end()); // iterator range wchar_t
PATH_IS(x, L"wstring");
x = string("std::string"); // container char
PATH_IS(x, L"std::string");
x = wstring(L"std::wstring"); // container wchar_t
PATH_IS(x, L"std::wstring");
x = "array char"; // array char
PATH_IS(x, L"array char");
x = L"array wchar"; // array wchar_t
PATH_IS(x, L"array wchar");
x = s.c_str(); // const char* null terminated
PATH_IS(x, L"string");
x = ws.c_str(); // const wchar_t* null terminated
PATH_IS(x, L"wstring");
}
// test_appends --------------------------------------------------------------------//
void test_appends()
{
std::cout << "testing appends..." << std::endl;
# ifdef BOOST_WINDOWS_API
# define BOOST_FS_FOO L"/foo\\"
# else // POSIX paths
# define BOOST_FS_FOO L"/foo/"
# endif
x = "/foo";
x /= path(""); // empty path
PATH_IS(x, L"/foo");
x = "/foo";
x /= path("/"); // slash path
PATH_IS(x, L"/foo/");
x = "/foo";
x /= path("/boo"); // slash path
PATH_IS(x, L"/foo/boo");
x = "/foo";
x /= x; // self-append
PATH_IS(x, L"/foo/foo");
x = "/foo";
x /= path("yet another path"); // another path
PATH_IS(x, BOOST_FS_FOO L"yet another path");
x = "/foo";
x.append(l.begin(), l.end()); // iterator range char
PATH_IS(x, BOOST_FS_FOO L"string");
x = "/foo";
x.append(wl.begin(), wl.end()); // iterator range wchar_t
PATH_IS(x, BOOST_FS_FOO L"wstring");
x = "/foo";
x /= string("std::string"); // container char
PATH_IS(x, BOOST_FS_FOO L"std::string");
x = "/foo";
x /= wstring(L"std::wstring"); // container wchar_t
PATH_IS(x, BOOST_FS_FOO L"std::wstring");
x = "/foo";
x /= "array char"; // array char
PATH_IS(x, BOOST_FS_FOO L"array char");
x = "/foo";
x /= L"array wchar"; // array wchar_t
PATH_IS(x, BOOST_FS_FOO L"array wchar");
x = "/foo";
x /= s.c_str(); // const char* null terminated
PATH_IS(x, BOOST_FS_FOO L"string");
x = "/foo";
x /= ws.c_str(); // const wchar_t* null terminated
PATH_IS(x, BOOST_FS_FOO L"wstring");
}
// test_observers ------------------------------------------------------------------//
void test_observers()
{
std::cout << "testing observers..." << std::endl;
path p0("abc");
CHECK(p0.native().size() == 3);
CHECK(p0.string() == "abc");
CHECK(p0.string().size() == 3);
CHECK(p0.wstring() == L"abc");
CHECK(p0.wstring().size() == 3);
# ifdef BOOST_WINDOWS_API
path p("abc\\def/ghi");
CHECK(std::wstring(p.c_str()) == L"abc\\def/ghi");
CHECK(p.string() == "abc\\def/ghi");
CHECK(p.wstring() == L"abc\\def/ghi");
CHECK(p.generic_string() == "abc/def/ghi");
CHECK(p.generic_wstring() == L"abc/def/ghi");
CHECK(p.generic_string<string>() == "abc/def/ghi");
CHECK(p.generic_string<wstring>() == L"abc/def/ghi");
CHECK(p.generic_string<path::string_type>() == L"abc/def/ghi");
# else // BOOST_POSIX_API
path p("abc\\def/ghi");
CHECK(string(p.c_str()) == "abc\\def/ghi");
CHECK(p.string() == "abc\\def/ghi");
CHECK(p.wstring() == L"abc\\def/ghi");
CHECK(p.generic_string() == "abc\\def/ghi");
CHECK(p.generic_wstring() == L"abc\\def/ghi");
CHECK(p.generic_string<string>() == "abc\\def/ghi");
CHECK(p.generic_string<wstring>() == L"abc\\def/ghi");
CHECK(p.generic_string<path::string_type>() == "abc\\def/ghi");
# endif
}
// test_relationals ----------------------------------------------------------------//
void test_relationals()
{
std::cout << "testing relationals..." << std::endl;
# ifdef BOOST_WINDOWS_API
// this is a critical use case to meet user expectations
CHECK(path("c:\\abc") == path("c:/abc"));
# endif
const path p("bar");
const path p2("baz");
CHECK(!(p < p));
CHECK(p < p2);
CHECK(!(p2 < p));
CHECK(p < "baz");
CHECK(p < string("baz"));
CHECK(p < L"baz");
CHECK(p < wstring(L"baz"));
CHECK(!("baz" < p));
CHECK(!(string("baz") < p));
CHECK(!(L"baz" < p));
CHECK(!(wstring(L"baz") < p));
CHECK(p == p);
CHECK(!(p == p2));
CHECK(!(p2 == p));
CHECK(p2 == "baz");
CHECK(p2 == string("baz"));
CHECK(p2 == L"baz");
CHECK(p2 == wstring(L"baz"));
CHECK("baz" == p2);
CHECK(string("baz") == p2);
CHECK(L"baz" == p2);
CHECK(wstring(L"baz") == p2);
CHECK(!(p != p));
CHECK(p != p2);
CHECK(p2 != p);
CHECK(p <= p);
CHECK(p <= p2);
CHECK(!(p2 <= p));
CHECK(!(p > p));
CHECK(!(p > p2));
CHECK(p2 > p);
CHECK(p >= p);
CHECK(!(p >= p2));
CHECK(p2 >= p);
}
// test_inserter_and_extractor -----------------------------------------------------//
void test_inserter_and_extractor()
{
std::cout << "testing inserter and extractor..." << std::endl;
path p1("foo bar"); // verify space in path roundtrips per ticket #3863
path p2;
std::stringstream ss;
CHECK(p1 != p2);
ss << p1;
ss >> p2;
CHECK(p1 == p2);
path wp1(L"foo bar");
path wp2;
std::wstringstream wss;
CHECK(wp1 != wp2);
wss << wp1;
wss >> wp2;
CHECK(wp1 == wp2);
}
// test_other_non_members ----------------------------------------------------------//
void test_other_non_members()
{
std::cout << "testing other_non_members..." << std::endl;
path p1("foo");
path p2("bar");
// operator /
CHECK(p1 / p2 == path("foo/bar").make_preferred());
CHECK("foo" / p2 == path("foo/bar").make_preferred());
CHECK(L"foo" / p2 == path("foo/bar").make_preferred());
CHECK(string("foo") / p2 == path("foo/bar").make_preferred());
CHECK(wstring(L"foo") / p2 == path("foo/bar").make_preferred());
CHECK(p1 / "bar" == path("foo/bar").make_preferred());
CHECK(p1 / L"bar" == path("foo/bar").make_preferred());
CHECK(p1 / string("bar") == path("foo/bar").make_preferred());
CHECK(p1 / wstring(L"bar") == path("foo/bar").make_preferred());
swap(p1, p2);
CHECK(p1 == "bar");
CHECK(p2 == "foo");
CHECK(path("").remove_filename() == "");
CHECK(path("foo").remove_filename() == "");
CHECK(path("foo/bar").remove_filename() == "foo");
}
// // test_modifiers ------------------------------------------------------------------//
//
// void test_modifiers()
// {
// std::cout << "testing modifiers..." << std::endl;
//
// }
// test_iterators ------------------------------------------------------------------//
void test_iterators()
{
std::cout << "testing iterators..." << std::endl;
path p1;
CHECK(p1.begin() == p1.end());
path p2("/");
CHECK(p2.begin() != p2.end());
CHECK(*p2.begin() == "/");
CHECK(++p2.begin() == p2.end());
path p3("foo/bar/baz");
path::iterator it(p3.begin());
CHECK(p3.begin() != p3.end());
CHECK(*it == "foo");
CHECK(*++it == "bar");
CHECK(*++it == "baz");
CHECK(*--it == "bar");
CHECK(*--it == "foo");
CHECK(*++it == "bar");
CHECK(*++it == "baz");
CHECK(++it == p3.end());
}
// test_modifiers ------------------------------------------------------------------//
void test_modifiers()
{
std::cout << "testing modifiers..." << std::endl;
// CHECK(path("").make_absolute("") == ""); // should assert
// CHECK(path("").make_absolute("foo") == ""); // should assert
# ifdef BOOST_WINDOWS_API
CHECK(path("baa").make_absolute("c:/") == "c:/baa");
CHECK(path("/baa").make_absolute("c:/foo").string() == path("c:/baa").string());
CHECK(path("baa/baz").make_absolute("c:/foo/bar").string()
== path("c:/foo/bar\\baa/baz").string());
# else
CHECK(path("baa").make_absolute("/") == "/baa");
CHECK(path("/baa").make_absolute("/foo").string() == path("/baa").string());
CHECK(path("baa/baz").make_absolute("/foo/bar").string()
== path("/foo/bar/baa/baz").string());
# endif
}
// test_decompositions -------------------------------------------------------------//
void test_decompositions()
{
std::cout << "testing decompositions..." << std::endl;
CHECK(path("").root_name().string() == "");
CHECK(path("foo").root_name().string() == "");
CHECK(path("/").root_name().string() == "");
CHECK(path("/foo").root_name().string() == "");
CHECK(path("//netname").root_name().string() == "//netname");
CHECK(path("//netname/foo").root_name().string() == "//netname");
CHECK(path("").root_directory().string() == "");
CHECK(path("foo").root_directory().string() == "");
CHECK(path("/").root_directory().string() == "/");
CHECK(path("/foo").root_directory().string() == "/");
CHECK(path("//netname").root_directory().string() == "");
CHECK(path("//netname/foo").root_directory().string() == "/");
CHECK(path("").root_path().string() == "");
CHECK(path("/").root_path().string() == "/");
CHECK(path("/foo").root_path().string() == "/");
CHECK(path("//netname").root_path().string() == "//netname");
CHECK(path("//netname/foo").root_path().string() == "//netname/");
# ifdef BOOST_WINDOWS_API
CHECK(path("c:/foo").root_path().string() == "c:/");
# endif
CHECK(path("").relative_path().string() == "");
CHECK(path("/").relative_path().string() == "");
CHECK(path("/foo").relative_path().string() == "foo");
CHECK(path("").parent_path().string() == "");
CHECK(path("/").parent_path().string() == "");
CHECK(path("/foo").parent_path().string() == "/");
CHECK(path("/foo/bar").parent_path().string() == "/foo");
CHECK(path("/foo/bar/baz.zoo").filename().string() == "baz.zoo");
CHECK(path("/foo/bar/baz.zoo").stem().string() == "baz");
CHECK(path("/foo/bar.woo/baz").stem().string() == "baz");
CHECK(path("foo.bar.baz.tar.bz2").extension().string() == ".bz2");
CHECK(path("/foo/bar/baz.zoo").extension().string() == ".zoo");
CHECK(path("/foo/bar.woo/baz").extension().string() == "");
}
// test_queries --------------------------------------------------------------------//
void test_queries()
{
std::cout << "testing queries..." << std::endl;
path p1("");
path p2("//netname/foo.doo");
CHECK(p1.empty());
CHECK(!p1.has_root_path());
CHECK(!p1.has_root_name());
CHECK(!p1.has_root_directory());
CHECK(!p1.has_relative_path());
CHECK(!p1.has_parent_path());
CHECK(!p1.has_filename());
CHECK(!p1.has_stem());
CHECK(!p1.has_extension());
CHECK(!p1.is_absolute());
CHECK(p1.is_relative());
CHECK(!p2.empty());
CHECK(p2.has_root_path());
CHECK(p2.has_root_name());
CHECK(p2.has_root_directory());
CHECK(p2.has_relative_path());
CHECK(p2.has_parent_path());
CHECK(p2.has_filename());
CHECK(p2.has_stem());
CHECK(p2.has_extension());
CHECK(p2.is_absolute());
CHECK(!p2.is_relative());
}
// test_imbue_locale ---------------------------------------------------------------//
void test_imbue_locale()
{
std::cout << "testing imbue locale..." << std::endl;
// \u2722 and \xE2\x9C\xA2 are UTF-16 and UTF-8 FOUR TEARDROP-SPOKED ASTERISK
std::cout << " testing p0 ..." << std::endl;
path p0(L"\u2722"); // for tests that depend on path_traits::convert
# ifdef BOOST_WINDOWS_API
CHECK(p0.string() != "\xE2\x9C\xA2");
# endif
string p0_string(p0.string());
std::cout << " testing p1 ..." << std::endl;
path p1("\xE2\x9C\xA2");
# ifdef BOOST_WINDOWS_API
CHECK(p1 != L"\u2722");
# endif
wstring p1_wstring(p1.wstring());
// So that tests are run with known encoding, use Boost UTF-8 codecvt
std::locale global_loc = std::locale();
std::locale loc(global_loc, new fs::detail::utf8_codecvt_facet);
std::cout << " imbuing locale ..." << std::endl;
std::locale old_loc = path::imbue(loc);
std::cout << " testing with the imbued locale ..." << std::endl;
CHECK(p0.string() == "\xE2\x9C\xA2");
path p2("\xE2\x9C\xA2");
CHECK(p2 == L"\u2722");
CHECK(p2.wstring() == L"\u2722");
std::cout << " imbuing the original locale ..." << std::endl;
path::imbue(old_loc);
std::cout << " testing with the original locale ..." << std::endl;
CHECK(p0.string() == p0_string);
path p3("\xE2\x9C\xA2");
# ifdef BOOST_WINDOWS_API
CHECK(p3 != L"\u2722");
# endif
CHECK(p3.wstring() == p1_wstring);
std::cout << " locale testing complete" << std::endl;
}
// test_overloads ------------------------------------------------------------------//
void test_overloads()
{
std::cout << "testing overloads..." << std::endl;
std::string s("hello");
const char a[] = "goodbye";
path p1(s);
path p2(s.c_str());
path p3(a);
path p4("foo");
std::wstring ws(L"hello");
const wchar_t wa[] = L"goodbye";
path wp1(ws);
path wp2(ws.c_str());
path wp3(wa);
path wp4(L"foo");
}
// test_error_handling -------------------------------------------------------------//
class error_codecvt
: public std::codecvt< wchar_t, char, std::mbstate_t >
{
public:
explicit error_codecvt()
: std::codecvt<wchar_t, char, std::mbstate_t>() {}
protected:
virtual bool do_always_noconv() const throw() { return false; }
virtual int do_encoding() const throw() { return 0; }
virtual std::codecvt_base::result do_in(std::mbstate_t&,
const char*, const char*, const char*&,
wchar_t*, wchar_t*, wchar_t*&) const
{
static std::codecvt_base::result r = std::codecvt_base::noconv;
if (r == std::codecvt_base::partial) r = std::codecvt_base::error;
else if (r == std::codecvt_base::error) r = std::codecvt_base::noconv;
else r = std::codecvt_base::partial;
return r;
}
virtual std::codecvt_base::result do_out(std::mbstate_t &,
const wchar_t*, const wchar_t*, const wchar_t*&,
char*, char*, char*&) const
{
static std::codecvt_base::result r = std::codecvt_base::noconv;
if (r == std::codecvt_base::partial) r = std::codecvt_base::error;
else if (r == std::codecvt_base::error) r = std::codecvt_base::noconv;
else r = std::codecvt_base::partial;
return r;
}
virtual std::codecvt_base::result do_unshift(std::mbstate_t&,
char*, char*, char* &) const { return ok; }
virtual int do_length(std::mbstate_t &,
const char*, const char*, std::size_t) const { return 0; }
virtual int do_max_length() const throw () { return 0; }
};
void test_error_handling()
{
std::cout << "testing error handling..." << std::endl;
std::locale global_loc = std::locale();
std::locale loc(global_loc, new error_codecvt);
std::cout << " imbuing error locale ..." << std::endl;
std::locale old_loc = path::imbue(loc);
// These tests rely on a path constructor that fails in the locale conversion.
// Thus construction has to call codecvt. Force that by using a narrow string
// for Windows, and a wide string for POSIX.
# ifdef BOOST_WINDOWS_API
# define STRING_FOO_ "foo"
# else
# define STRING_FOO_ L"foo"
# endif
{
std::cout << " testing std::codecvt_base::partial error..." << std::endl;
bool exception_thrown (false);
try { path(STRING_FOO_); }
catch (const bs::system_error & ex)
{
exception_thrown = true;
BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::partial,
fs::codecvt_error_category()));
}
catch (...) { std::cout << "***** unexpected exception type *****" << std::endl; }
BOOST_TEST(exception_thrown);
}
{
std::cout << " testing std::codecvt_base::error error..." << std::endl;
bool exception_thrown (false);
try { path(STRING_FOO_); }
catch (const bs::system_error & ex)
{
exception_thrown = true;
BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::error,
fs::codecvt_error_category()));
}
catch (...) { std::cout << "***** unexpected exception type *****" << std::endl; }
BOOST_TEST(exception_thrown);
}
{
std::cout << " testing std::codecvt_base::noconv error..." << std::endl;
bool exception_thrown (false);
try { path(STRING_FOO_); }
catch (const bs::system_error & ex)
{
exception_thrown = true;
BOOST_TEST_EQ(ex.code(), bs::error_code(std::codecvt_base::noconv,
fs::codecvt_error_category()));
}
catch (...) { std::cout << "***** unexpected exception type *****" << std::endl; }
BOOST_TEST(exception_thrown);
}
std::cout << " restoring original locale ..." << std::endl;
path::imbue(old_loc);
}
# if 0
// // test_locales --------------------------------------------------------------------//
//
// void test_locales()
// {
// std::cout << "testing locales..." << std::endl;
//
// }
// test_user_supplied_type ---------------------------------------------------------//
typedef std::basic_string<int> user_string;
} // unnamed namespace
namespace boost
{
namespace filesystem
{
namespace path_traits
{
template<> struct is_iterator<const user_string::value_type *> { static const bool value = true; };
template<> struct is_iterator<user_string::value_type *> { static const bool value = true; };
template<> struct is_iterator<user_string::iterator> { static const bool value = true; };
template<> struct is_iterator<user_string::const_iterator> { static const bool value = true; };
template<> struct is_container<user_string> { static const bool value = true; };
template<>
void append<user_string::value_type>(const user_string::value_type * begin,
const user_string::value_type * end, string_type & target, system::error_code & ec)
{
for (; begin != end && *begin; ++begin)
target += *begin + 1; // change so that results distinguishable from char cvts
}
# ifdef __GNUC__
// This specialization shouldn't be needed, and VC++, Intel, and others work
// fine without it. But gcc 4.3.2, and presumably other versions, need it.
template<>
void append<user_string::value_type>(const user_string::value_type * begin,
string_type & target, system::error_code & ec)
{
path_traits::append<user_string::value_type>(begin,
static_cast<const user_string::value_type *>(0), target, ec);
}
# endif
template<>
user_string convert<user_string>(const string_type & source,
system::error_code & ec)
{
user_string temp;
for (string_type::const_iterator it = source.begin();
it != source.end(); ++it)
temp += *it - 1;
return temp;
}
} // namespace path_traits
} // namespace filesystem
} // namespace boost
namespace
{
void test_user_supplied_type()
{
std::cout << "testing user supplied type..." << std::endl;
user_string::value_type usr_c_str[] = { 'a', 'b', 'c', 0 };
user_string usr(usr_c_str);
path p1(usr.c_str());
CHECK(p1 == path("bcd"));
CHECK(p1 == "bcd");
user_string s1(p1.string<user_string>());
CHECK(s1 == usr);
}
# endif
} // unnamed namespace
//--------------------------------------------------------------------------------------//
// //
// main //
// //
//--------------------------------------------------------------------------------------//
int main(int, char*[])
{
// document state of critical macros
#ifdef BOOST_POSIX_API
cout << "BOOST_POSIX_API" << endl;
#endif
#ifdef BOOST_WINDOWS_API
cout << "BOOST_WINDOWS_API" << endl;
#endif
#ifdef BOOST_POSIX_API
cout << "BOOST_PATH_API" << endl;
#endif
#ifdef BOOST_WINDOWS_API
cout << "BOOST_WINDOWS_API" << endl;
#endif
l.push_back('s');
l.push_back('t');
l.push_back('r');
l.push_back('i');
l.push_back('n');
l.push_back('g');
wl.push_back(L'w');
wl.push_back(L's');
wl.push_back(L't');
wl.push_back(L'r');
wl.push_back(L'i');
wl.push_back(L'n');
wl.push_back(L'g');
v.push_back('f');
v.push_back('u');
v.push_back('z');
wv.push_back(L'w');
wv.push_back(L'f');
wv.push_back(L'u');
wv.push_back(L'z');
test_overloads();
test_constructors();
test_assignments();
test_appends();
test_modifiers();
test_observers();
test_relationals();
test_inserter_and_extractor();
test_other_non_members();
test_iterators();
test_decompositions();
test_queries();
test_imbue_locale();
test_error_handling();
# if 0
test_user_supplied_type();
#endif
std::string foo("\\abc");
const char* bar = "/abc";
if (foo == bar)
cout << "unintended consequence\n";
return ::boost::report_errors();
}