Re: [libstdc++-v3][C++14] Implement N3654 - Quoted Strings

2013-06-05 Thread Jonathan Wakely
On 5 June 2013 20:18, Ed Smith-Rowland wrote:
> Greetings,
> This patch implements quoted string manipulators for C++14.
>
> 27.7.6 - Quoted manipulators[quoted.manip].
>
> The idea is to allow round trip insert and extract of strings with spaces.
>
>   std::stringstream ss;
>   std::string original = "thing1  thing1";
>   std::string round_trip;
>   ss << std::quoted(original);
>   ss >> std::quoted(round_trip);
>   assert( original == round_trip );
>
> Builds and tests clean on x86-64-linux.

As I suggested for your literals patch, couldn't the test for:
#if __cplusplus > 201103L
go inside the existing one?

i.e.

#if __cplusplus >= 201103L
[...]
#if __cplusplus > 201103L
[...]
#endif
#endif


_Quoted_string appears to do two copies of the string, one for the
constructor argument and one for the member variable, do they
definitely get elided?

The members of _Quoted_string should be named _M_xxx not __xxx, to
follow the coding style guidelines.

What is __delim2 for?

What if the first extraction in the operator>> fails, is doing
__is.unget() the right thing to do?

You could simplify the quoted() overloads by using auto return type
deduction, is it an intentional choice not to use that?


Re: [libstdc++-v3][C++14] Implement N3654 - Quoted Strings

2013-06-06 Thread Ed Smith-Rowland

On 06/05/2013 04:01 PM, Jonathan Wakely wrote:

On 5 June 2013 20:18, Ed Smith-Rowland wrote:

Greetings,
This patch implements quoted string manipulators for C++14.

27.7.6 - Quoted manipulators[quoted.manip].

The idea is to allow round trip insert and extract of strings with spaces.

   std::stringstream ss;
   std::string original = "thing1  thing1";
   std::string round_trip;
   ss << std::quoted(original);
   ss >> std::quoted(round_trip);
   assert( original == round_trip );

Builds and tests clean on x86-64-linux.

As I suggested for your literals patch, couldn't the test for:
#if __cplusplus > 201103L
go inside the existing one?

i.e.

#if __cplusplus >= 201103L
[...]
#if __cplusplus > 201103L
[...]
#endif
#endif
Certainly.  I forgot that in the last literals patch.  I'll fix that 
after I finish this one. (I just noticed junk comments in the testcases 
for literals also).



_Quoted_string appears to do two copies of the string, one for the
constructor argument and one for the member variable, do they
definitely get elided?
I looks that way.  But all used of the template parm String are either 
references or pointers so these operations should be efficient.

_Quoted_string should be used as a non-owning string thing.


The members of _Quoted_string should be named _M_xxx not __xxx, to
follow the coding style guidelines.

Done.


What is __delim2 for?

What if the first extraction in the operator>> fails, is doing
__is.unget() the right thing to do?

Thanks. I'll return with __is rather than attempting to continue reading.


You could simplify the quoted() overloads by using auto return type
deduction, is it an intentional choice not to use that?
For some reason I forgot about auto return type in C++14.  It sure 
cleans things up nicely.  Done.

Rebuilt and retested on x86_64


2013-06-05  Ed Smith-Rowland  <3dw...@verizon.net>

Implement N3654 - Quoted Strings Library Proposal
* include/std/iomanip: Add quoted(String, Char delim, Char escape)
manipulators and supporting machinery in c++1y mode.
* testsuite/27_io/manipulators/standard/char/quoted.cc: New.
* testsuite/27_io/manipulators/standard/wchar_t/quoted.cc: New.
Index: include/std/iomanip
===
--- include/std/iomanip (revision 199730)
+++ include/std/iomanip (working copy)
@@ -334,8 +334,157 @@
   return __os; 
 }
 
-#endif
+#if __cplusplus > 201103L
 
+  namespace __detail {
+
+/**
+ * @brief Struct for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  struct _Quoted_string
+  {
+   _Quoted_string(_String __str, _CharT __del, _CharT __esc)
+   : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
+   { }
+
+   _Quoted_string&
+   operator=(_Quoted_string&) = delete;
+
+   _String _M_string;
+   _CharT _M_delim;
+   _CharT _M_escape;
+  };
+
+/**
+ * @brief Inserter for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+const _Quoted_string& __str)
+  {
+   __os << __str._M_delim;
+   for (const _CharT* __c = __str._M_string; *__c; ++__c)
+ {
+   if (*__c == __str._M_delim || *__c == __str._M_escape)
+ __os << __str._M_escape;
+   __os << *__c;
+ }
+   __os << __str._M_delim;
+
+   return __os;
+  }
+
+/**
+ * @brief Inserter for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+const _Quoted_string<_String, _CharT>& __str)
+  {
+   __os << __str._M_delim;
+   for (auto& __c : __str._M_string)
+ {
+   if (__c == __str._M_delim || __c == __str._M_escape)
+ __os << __str._M_escape;
+   __os << __c;
+ }
+   __os << __str._M_delim;
+
+   return __os;
+  }
+
+/**
+ * @brief Extractor for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator>>(std::basic_istream<_CharT, _Traits>& __is,
+const _Quoted_string&,
+ _CharT>& __str)
+  {
+   __str._M_string.clear();
+
+   _CharT __c;
+   __is >> __c;
+   if (!__is.good())
+ return __is;
+   if (__c != __str._M_delim)
+ {
+   __is.unget();
+   __is >> __str._M_string;
+   return __is;
+ }
+   std::ios_base::fmtflags __flags
+ = __is.flags(__is.flags() & ~std::ios_base::skipws);
+   do
+ {
+   __is >> __c;
+   if (!__is.good())
+ break;
+   if (__c == __str._M_escape)
+ 

Re: [libstdc++-v3][C++14] Implement N3654 - Quoted Strings

2013-06-07 Thread Ed Smith-Rowland

On 06/06/2013 10:55 AM, Ed Smith-Rowland wrote:

On 06/05/2013 04:01 PM, Jonathan Wakely wrote:

On 5 June 2013 20:18, Ed Smith-Rowland wrote:

Greetings,
This patch implements quoted string manipulators for C++14.

27.7.6 - Quoted manipulators[quoted.manip].

The idea is to allow round trip insert and extract of strings with 
spaces.


   std::stringstream ss;
   std::string original = "thing1  thing1";
   std::string round_trip;
   ss << std::quoted(original);
   ss >> std::quoted(round_trip);
   assert( original == round_trip );

Builds and tests clean on x86-64-linux.

As I suggested for your literals patch, couldn't the test for:
#if __cplusplus > 201103L
go inside the existing one?

i.e.

#if __cplusplus >= 201103L
[...]
#if __cplusplus > 201103L
[...]
#endif
#endif
Certainly.  I forgot that in the last literals patch.  I'll fix that 
after I finish this one. (I just noticed junk comments in the 
testcases for literals also).



_Quoted_string appears to do two copies of the string, one for the
constructor argument and one for the member variable, do they
definitely get elided?
I looks that way.  But all used of the template parm String are either 
references or pointers so these operations should be efficient.

_Quoted_string should be used as a non-owning string thing.


The members of _Quoted_string should be named _M_xxx not __xxx, to
follow the coding style guidelines.

Done.


What is __delim2 for?

What if the first extraction in the operator>> fails, is doing
__is.unget() the right thing to do?

Thanks. I'll return with __is rather than attempting to continue reading.


You could simplify the quoted() overloads by using auto return type
deduction, is it an intentional choice not to use that?
For some reason I forgot about auto return type in C++14.  It sure 
cleans things up nicely.  Done.

Rebuilt and retested on x86_64



OK, I added a static_assert to check that _String is only reference or 
pointer.
I also added a tests that check the case where _String is 'const 
basic_string<>&'.


Built and tested on x86_64-linux.

OK?

Ed


2013-06-08  Ed Smith-Rowland  <3dw...@verizon.net>

Implement N3654 - Quoted Strings Library Proposal
* include/std/iomanip: Add quoted(String, Char delim, Char escape)
manipulators and supporting machinery in c++1y mode.
* testsuite/27_io/manipulators/standard/char/quoted.cc: New.
* testsuite/27_io/manipulators/standard/wchar_t/quoted.cc: New.
Index: include/std/iomanip
===
--- include/std/iomanip (revision 199730)
+++ include/std/iomanip (working copy)
@@ -334,8 +334,161 @@
   return __os; 
 }
 
-#endif
+#if __cplusplus > 201103L
 
+  namespace __detail {
+
+/**
+ * @brief Struct for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  struct _Quoted_string
+  {
+   static_assert(is_reference<_String>::value
+  || is_pointer<_String>::value,
+ "String type must be pointer or reference");
+
+   _Quoted_string(_String __str, _CharT __del, _CharT __esc)
+   : _M_string(__str), _M_delim{__del}, _M_escape{__esc}
+   { }
+
+   _Quoted_string&
+   operator=(_Quoted_string&) = delete;
+
+   _String _M_string;
+   _CharT _M_delim;
+   _CharT _M_escape;
+  };
+
+/**
+ * @brief Inserter for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+const _Quoted_string& __str)
+  {
+   __os << __str._M_delim;
+   for (const _CharT* __c = __str._M_string; *__c; ++__c)
+ {
+   if (*__c == __str._M_delim || *__c == __str._M_escape)
+ __os << __str._M_escape;
+   __os << *__c;
+ }
+   __os << __str._M_delim;
+
+   return __os;
+  }
+
+/**
+ * @brief Inserter for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator<<(std::basic_ostream<_CharT, _Traits>& __os,
+const _Quoted_string<_String, _CharT>& __str)
+  {
+   __os << __str._M_delim;
+   for (auto& __c : __str._M_string)
+ {
+   if (__c == __str._M_delim || __c == __str._M_escape)
+ __os << __str._M_escape;
+   __os << __c;
+ }
+   __os << __str._M_delim;
+
+   return __os;
+  }
+
+/**
+ * @brief Extractor for delimited strings.
+ *The left and right delimiters can be different.
+ */
+template
+  auto&
+  operator>>(std::basic_istream<_CharT, _Traits>& __is,
+const _Quoted_string&,
+ _CharT>& __str)
+  {
+   __str._M_string.clear();
+
+   _CharT __c;
+   __is >> __c;
+   if (!_

Re: [libstdc++-v3][C++14] Implement N3654 - Quoted Strings

2013-06-08 Thread Jonathan Wakely
On 6 June 2013 15:55, Ed Smith-Rowland wrote:
> On 06/05/2013 04:01 PM, Jonathan Wakely wrote:
>>
>>
>> _Quoted_string appears to do two copies of the string, one for the
>> constructor argument and one for the member variable, do they
>> definitely get elided?
>
> I looks that way.  But all used of the template parm String are either
> references or pointers so these operations should be efficient.

Ahh, I didn't notice that, sorry.


Re: [libstdc++-v3][C++14] Implement N3654 - Quoted Strings

2013-06-08 Thread Jonathan Wakely
On 8 June 2013 04:44, Ed Smith-Rowland wrote:
>
> OK, I added a static_assert to check that _String is only reference or
> pointer.
> I also added a tests that check the case where _String is 'const
> basic_string<>&'.
>
> Built and tested on x86_64-linux.
>
> OK?

This is OK to commit to trunk. Thanks, Ed!