|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r63017 - in branches/filesystem3: boost libs/filesystem/v3/test
From: bdawes_at_[hidden]
Date: 2010-06-16 08:58:22
Author: bemandawes
Date: 2010-06-16 08:58:22 EDT (Wed, 16 Jun 2010)
New Revision: 63017
URL: http://svn.boost.org/trac/boost/changeset/63017
Log:
Fix all known issues, wishes
Text files modified:
branches/filesystem3/boost/delimit_string.hpp | 133 +++++++++++++++++++++++++--------------
branches/filesystem3/libs/filesystem/v3/test/delim_string_test.cpp | 26 +++---
2 files changed, 98 insertions(+), 61 deletions(-)
Modified: branches/filesystem3/boost/delimit_string.hpp
==============================================================================
--- branches/filesystem3/boost/delimit_string.hpp (original)
+++ branches/filesystem3/boost/delimit_string.hpp 2010-06-16 08:58:22 EDT (Wed, 16 Jun 2010)
@@ -11,48 +11,24 @@
#include <istream>
#include <ostream>
#include <string>
-#include <sstream>
-#include <iomanip>
+#include <boost/io/ios_state.hpp>
namespace boost
{
- namespace string
+ namespace detail
{
- namespace detail
- {
- // ostream operator<< takes a const_proxy& argument, and thus works for arguments
- // of both type const_proxy and type proxy. istream operator>> takes a proxy&
- // argument, and thus works for arguments of type proxy but not type const_proxy.
- // That's what ensures const strings can't be inadvertently written into, not
- // whether or not const_proxy::s is const.
- template <class String>
- struct const_proxy
- {
- typedef typename String::value_type value_type;
- String& s; // must be non-const
- value_type escape;
- value_type delim;
- const_proxy(std::string& s_, value_type escape_, value_type delim_)
- : s(s_), escape(escape_), delim(delim_) {}
- };
-
- template <class String>
- struct proxy : public const_proxy<String>
- {
- proxy(String& s_, value_type escape_, value_type delim_)
- : const_proxy(s_, escape_, delim_ ) {}
- };
- }
+ // inserter support
template <class String>
- inline detail::const_proxy<String> delimit_string(const String& s,
- typename String::value_type escape='\\',
- typename String::value_type delim='\"')
- {
- // const safety is provided by the detail::proxy - detail::const_proxy relationship,
- // so we are not giving up type safety by casting away const.
- return detail::const_proxy<String>(const_cast<std::string&>(s), escape, delim);
- }
+ struct const_proxy
+ {
+ typedef typename String::value_type value_type;
+ const String& s;
+ value_type escape;
+ value_type delim;
+ const_proxy(const String& s_, value_type escape_, value_type delim_)
+ : s(s_), escape(escape_), delim(delim_) {}
+ };
template <class String>
std::basic_ostream<typename String::value_type>&
@@ -73,14 +49,46 @@
return os;
}
- template <class String>
- inline detail::proxy<String> delimit_string(String& s,
- typename String::value_type escape='\\',
- typename String::value_type delim='\"')
+ template <class Char>
+ struct c_str_proxy
{
- return detail::proxy<String>(s, escape, delim);
+ const Char* s;
+ Char escape;
+ Char delim;
+ c_str_proxy(const Char* s_, Char escape_, Char delim_)
+ : s(s_), escape(escape_), delim(delim_) {}
+ };
+
+ template <class Char>
+ std::basic_ostream<Char>&
+ operator<<(std::basic_ostream<Char>& os, const detail::c_str_proxy<Char>& prox)
+ {
+ os << prox.delim;
+ for (const Char* it = prox.s;
+ *it;
+ ++it )
+ {
+ if (*it == prox.delim || *it == prox.escape)
+ os << prox.escape;
+ os << *it;
+ }
+ os << prox.delim;
+ return os;
}
+ // extractor support
+
+ template <class String>
+ struct proxy
+ {
+ typedef typename String::value_type value_type;
+ String& s;
+ value_type escape;
+ value_type delim;
+ proxy(String& s_, value_type escape_, value_type delim_)
+ : s(s_), escape(escape_), delim(delim_) {}
+ };
+
template <class String>
std::basic_istream<typename String::value_type>&
operator>>(std::basic_istream<typename String::value_type>& is,
@@ -95,18 +103,47 @@
return is;
}
prox.s.clear();
- for (;;)
{
- is >> std::noskipws >> c; //************ save and restore?
- if (c == prox.escape)
+ boost::io::ios_flags_saver ifs(is);
+ is >> std::noskipws;
+ for (;;)
+ {
is >> c;
- else if (c == prox.delim)
- break;
- prox.s += c;
+ if (c == prox.escape)
+ is >> c;
+ else if (c == prox.delim)
+ break;
+ prox.s += c;
+ }
}
return is;
}
- } // namespace string
+
+ } // namespace detail
+
+ template <class String>
+ inline detail::const_proxy<String> delimit(const String& s,
+ typename String::value_type escape='\\',
+ typename String::value_type delim='\"')
+ {
+ return detail::const_proxy<String>(s, escape, delim);
+ }
+
+ template <class Char>
+ inline detail::c_str_proxy<Char> delimit(const Char* s,
+ Char escape='\\',
+ Char delim='\"')
+ {
+ return detail::c_str_proxy<Char>(s, escape, delim);
+ }
+
+ template <class String>
+ inline detail::proxy<String> undelimit(String& s,
+ typename String::value_type escape='\\',
+ typename String::value_type delim='\"')
+ {
+ return detail::proxy<String>(s, escape, delim);
+ }
} // namespace boost
#endif // BOOST_DELIMIT_STRING
Modified: branches/filesystem3/libs/filesystem/v3/test/delim_string_test.cpp
==============================================================================
--- branches/filesystem3/libs/filesystem/v3/test/delim_string_test.cpp (original)
+++ branches/filesystem3/libs/filesystem/v3/test/delim_string_test.cpp 2010-06-16 08:58:22 EDT (Wed, 16 Jun 2010)
@@ -1,29 +1,29 @@
#include <boost/delimit_string.hpp>
#include <iostream>
+#include <sstream>
#include <cassert>
-using boost::string::delimit_string;
-
-// Should these two operators be in the global namespace?
-using boost::string::operator<<;
-using boost::string::operator>>;
+using boost::delimit;
+using boost::undelimit;
int main()
{
- std::cout << delimit_string(std::string("foo\\bar, \" *")) << std::endl;
- //std::cout << delimit_string("foo & bar, \" *", '&') << std::endl;
- //std::cout << delimit_string("foo & bar, * ", '&', '*') << std::endl;
+ std::cout << delimit("foo\\bar, \" *") << std::endl;
+ std::cout << delimit("foo & bar, \" *", '&') << std::endl;
+ std::cout << delimit("foo & bar, * ", '&', '*') << std::endl;
+
+ std::wcout << delimit(L"foo$bar, \" *", L'$') << std::endl;
std::string non_const_string("non_const_string");
- std::cout << delimit_string(non_const_string) << '\n';
+ std::cout << delimit(non_const_string) << '\n';
std::stringstream ss;
const std::string expected("foo\\bar, \" *");
std::string actual;
- ss << delimit_string(expected) << '\n';
- ss >> delimit_string<std::string>(actual);
+ ss << delimit(expected);
+ ss >> undelimit(actual);
std::cout << "round trip tests...\n";
std::cout << " expected--: " << expected << '\n';
@@ -32,8 +32,8 @@
assert(expected == actual);
// each of these should fail to compile because they are const:
- // ss >> delimit_string(expected);
- // ss >> delimit_string("foo");
+ // ss >> undelimit(expected);
+ // ss >> undelimit("foo");
return 0;
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk