Boost logo

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