diff mbox

libstdc++/61374 fix string_view conversion and update to latest draft

Message ID 20140601172422.GP6953@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely June 1, 2014, 5:24 p.m. UTC
Tested x86_64-linux, committed to trunk.

This should probably go on the 4.9 branch too, although we could leave
the old default cosntructor semantics and just fix the conversion
operator.

Comments

Daniel Krügler June 1, 2014, 7:07 p.m. UTC | #1
2014-06-01 19:24 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
> Tested x86_64-linux, committed to trunk.
>
> This should probably go on the 4.9 branch too, although we could leave
> the old default cosntructor semantics and just fix the conversion
> operator.

Looking at the comparison functions of basic_string_view I noticed
that these are not constexpr (nor seem to be other functions such as
find()).

- Daniel
Marc Glisse June 1, 2014, 7:26 p.m. UTC | #2
On Sun, 1 Jun 2014, Daniel Krügler wrote:

> 2014-06-01 19:24 GMT+02:00 Jonathan Wakely <jwakely@redhat.com>:
>> Tested x86_64-linux, committed to trunk.
>>
>> This should probably go on the 4.9 branch too, although we could leave
>> the old default cosntructor semantics and just fix the conversion
>> operator.
>
> Looking at the comparison functions of basic_string_view I noticed
> that these are not constexpr (nor seem to be other functions such as
> find()).

We may want to wait until the compiler supports C++14 constexpr, trying to 
implement it with C++11 would be doable but not so useful in my opinion.
Jonathan Wakely Aug. 4, 2014, 6:51 p.m. UTC | #3
On 01/06/14 18:24 +0100, Jonathan Wakely wrote:
>Tested x86_64-linux, committed to trunk.
>
>This should probably go on the 4.9 branch too, although we could leave
>the old default cosntructor semantics and just fix the conversion
>operator.

Now committed to the 4.9 branch too.

>    	PR libstdc++/61374
>    	* include/experimental/string_view (operator basic_string): Correct
>    	order of arguments.
>    	(to_string): Replace with member function.
>    	Add inline specifiers. Remove unused header. Remove _S_empty_rep and
>    	allow _M_str to be null.
>    	* testsuite/experimental/string_view/cons/char/1.cc: Adjust to new
>    	default constructor semantics.
>    	* testsuite/experimental/string_view/cons/wchar_t/1.cc: Likewise.
>    	* testsuite/experimental/string_view/operations/copy/char/1.cc: Fix
>    	copyright dates. Remove unused header.
>    	* testsuite/experimental/string_view/operations/copy/wchar_t/1.cc:
>    	Likewise.
>    	* testsuite/experimental/string_view/operations/data/char/1.cc:
>    	Fix copyright dates. Adjust to new default constructor semantics.
>    	* testsuite/experimental/string_view/operations/data/wchar_t/1.cc:
>    	Likewise.
>    	* testsuite/experimental/string_view/operations/to_string/1.cc: New.
diff mbox

Patch

commit a10c692b32082fa5cf00f2cdc92d44ffa79e3d43
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Jun 1 14:19:07 2014 +0100

    	PR libstdc++/61374
    	* include/experimental/string_view (operator basic_string): Correct
    	order of arguments.
    	(to_string): Replace with member function.
    	Add inline specifiers. Remove unused header. Remove _S_empty_rep and
    	allow _M_str to be null.
    	* testsuite/experimental/string_view/cons/char/1.cc: Adjust to new
    	default constructor semantics.
    	* testsuite/experimental/string_view/cons/wchar_t/1.cc: Likewise.
    	* testsuite/experimental/string_view/operations/copy/char/1.cc: Fix
    	copyright dates. Remove unused header.
    	* testsuite/experimental/string_view/operations/copy/wchar_t/1.cc:
    	Likewise.
    	* testsuite/experimental/string_view/operations/data/char/1.cc:
    	Fix copyright dates. Adjust to new default constructor semantics.
    	* testsuite/experimental/string_view/operations/data/wchar_t/1.cc:
    	Likewise.
    	* testsuite/experimental/string_view/operations/to_string/1.cc: New.

diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index 6b6588b..49f46af 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -39,7 +39,6 @@ 
 # include <bits/c++14_warning.h>
 #else
 
-#include <debug/debug.h>
 #include <string>
 #include <limits>
 
@@ -66,18 +65,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *    _CharT*    _M_str
    *    size_t     _M_len
    *  @endcode
-   *
-   *  A basic_string_view represents an empty string with a static constexpr
-   *  length one string:
-   *
-   *  @code
-   *    static constexpr value_type _S_empty_str[1]{0};
-   *  @endcode
    */
-  template<typename _CharT, typename _Traits = char_traits<_CharT>>
+  template<typename _CharT, typename _Traits = std::char_traits<_CharT>>
     class basic_string_view
     {
-
     public:
 
       // types
@@ -99,7 +90,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       constexpr
       basic_string_view() noexcept
-      : _M_len{0}, _M_str{_S_empty_str}
+      : _M_len{0}, _M_str{nullptr}
       { }
 
       constexpr basic_string_view(const basic_string_view&) noexcept = default;
@@ -112,12 +103,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       constexpr basic_string_view(const _CharT* __str)
       : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
-	_M_str{__str == nullptr ? _S_empty_str : __str}
+	_M_str{__str}
       { }
 
       constexpr basic_string_view(const _CharT* __str, size_type __len)
-      : _M_len{__str == nullptr ? 0 :__len},
-        _M_str{__str == nullptr ? _S_empty_str : __str}
+      : _M_len{__len},
+        _M_str{__str}
       { }
 
       basic_string_view&
@@ -143,19 +134,19 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       const_reverse_iterator
       rbegin() const noexcept
-      { return std::reverse_iterator<const_iterator>(this->end()); }
+      { return const_reverse_iterator(this->end()); }
 
       const_reverse_iterator
       rend() const noexcept
-      { return std::reverse_iterator<const_iterator>(this->begin()); }
+      { return const_reverse_iterator(this->begin()); }
 
       const_reverse_iterator
       crbegin() const noexcept
-      { return std::reverse_iterator<const_iterator>(this->end()); }
+      { return const_reverse_iterator(this->end()); }
 
       const_reverse_iterator
       crend() const noexcept
-      { return std::reverse_iterator<const_iterator>(this->begin()); }
+      { return const_reverse_iterator(this->begin()); }
 
       // [string.view.capacity], capacity
 
@@ -169,8 +160,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       constexpr size_type
       max_size() const noexcept
-      { return ((npos - sizeof(size_type) - sizeof(void*))
-		/ sizeof(value_type) / 4); }
+      {
+	return (npos - sizeof(size_type) - sizeof(void*))
+		/ sizeof(value_type) / 4;
+      }
 
       constexpr bool
       empty() const noexcept
@@ -195,7 +188,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 					     "(which is %zu) >= this->size() "
 					     "(which is %zu)"),
 					 __pos, this->size()),
-		_S_empty_str[0]);
+		*this->_M_str);
       }
 
       constexpr const _CharT&
@@ -219,11 +212,12 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return this->_M_str; }
 
       // [string.view.modifiers], modifiers:
+
       void
       clear() noexcept
       {
 	this->_M_len = 0;
-	this->_M_str = _S_empty_str;
+	this->_M_str = nullptr;
       }
 
       void
@@ -251,8 +245,14 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       template<typename _Allocator>
         explicit operator basic_string<_CharT, _Traits, _Allocator>() const
         {
-	  return basic_string<_CharT, _Traits, _Allocator>
-					(this->_M_len, this->_M_str);
+	  return { this->_M_str, this->_M_len };
+	}
+
+      template<typename _Allocator = std::allocator<_CharT>>
+	basic_string<_CharT, _Traits, _Allocator>
+	to_string(const _Allocator& __alloc = _Allocator()) const
+	{
+	  return { this->_M_str, this->_M_len, __alloc };
 	}
 
       size_type
@@ -431,8 +431,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	     : static_cast<int>(difference_type{__n1 - __n2});
       }
 
-      static constexpr value_type _S_empty_str[1]{};
-
       size_t	    _M_len;
       const _CharT* _M_str;
     };
@@ -456,131 +454,119 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator==(basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) == 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator==(basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return __x.compare(__y) == 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) == 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator!=(basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return !(__x == __y); }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator!=(basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return !(__x == __y); }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return !(__x == __y); }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator< (basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) < 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator< (basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return __x.compare(__y) < 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) < 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator> (basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) > 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator> (basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return __x.compare(__y) > 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) > 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator<=(basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) <= 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator<=(basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return __x.compare(__y) <= 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) <= 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator>=(basic_string_view<_CharT, _Traits> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) >= 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator>=(basic_string_view<_CharT, _Traits> __x,
                __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
     { return __x.compare(__y) >= 0; }
 
   template<typename _CharT, typename _Traits>
-    bool
+    inline bool
     operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
                basic_string_view<_CharT, _Traits> __y) noexcept
     { return __x.compare(__y) >= 0; }
 
-  // [string.view.comparison], sufficient additional overloads of comparison functions
-
-  // [string.view.nonmem], other non-member basic_string_view functions
-  template<typename _CharT, typename _Traits = char_traits<_CharT>,
-           typename _Allocator = allocator<_CharT>>
-    basic_string<_CharT, _Traits, _Allocator>
-    to_string(basic_string_view<_CharT, _Traits> __str,
-	      const _Allocator& __alloc = _Allocator())
-    {
-      return basic_string<_CharT, _Traits, _Allocator>
-			(__str.begin(), __str.end(), __alloc);
-    }
-
+  // [string.view.io], Inserters and extractors
   template<typename _CharT, typename _Traits>
-    basic_ostream<_CharT, _Traits>&
-      operator<<(basic_ostream<_CharT, _Traits>& __os,
-                 basic_string_view<_CharT,_Traits> __str)
-      { return __ostream_insert(__os, __str.data(), __str.size()); }
+    inline basic_ostream<_CharT, _Traits>&
+    operator<<(basic_ostream<_CharT, _Traits>& __os,
+	       basic_string_view<_CharT,_Traits> __str)
+    { return __ostream_insert(__os, __str.data(), __str.size()); }
 
 
   // basic_string_view typedef names
diff --git a/libstdc++-v3/include/experimental/string_view.tcc b/libstdc++-v3/include/experimental/string_view.tcc
index 1af3a4d..4456266 100644
--- a/libstdc++-v3/include/experimental/string_view.tcc
+++ b/libstdc++-v3/include/experimental/string_view.tcc
@@ -47,10 +47,6 @@  namespace experimental
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _CharT, typename _Traits>
-    constexpr _CharT
-    basic_string_view<_CharT, _Traits>::_S_empty_str[1];
-
-  template<typename _CharT, typename _Traits>
     typename basic_string_view<_CharT, _Traits>::size_type
     basic_string_view<_CharT, _Traits>::
     find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
diff --git a/libstdc++-v3/testsuite/experimental/string_view/cons/char/1.cc b/libstdc++-v3/testsuite/experimental/string_view/cons/char/1.cc
index c879cc7..a443b0a 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/cons/char/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/cons/char/1.cc
@@ -33,7 +33,7 @@  test01()
   // basic_string_view()
   const std::experimental::string_view str00{};
   VERIFY( str00.length() == 0 );
-  VERIFY( str00.data() != nullptr );
+  VERIFY( str00.data() == nullptr );
 
   // basic_string_view(const char*)
   const char str_lit01[] = "rodeo beach, marin";
@@ -54,11 +54,6 @@  test01()
   VERIFY( str05.length() == len_lit01 );
   VERIFY( str05.data() == str_lit01 );
 
-  //  basic_string_view(const char* s, std::size_t l)
-  std::experimental::string_view str06{nullptr, len_lit01};
-  VERIFY( str06.length() == 0 );
-  VERIFY( str06.data() != nullptr );
-
   // basic_string_view(basic_string& s)
   std::string istr07(10, 'z');
   std::experimental::string_view str07{istr07};
diff --git a/libstdc++-v3/testsuite/experimental/string_view/cons/wchar_t/1.cc b/libstdc++-v3/testsuite/experimental/string_view/cons/wchar_t/1.cc
index 12db72f..9ba9b84 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/cons/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/cons/wchar_t/1.cc
@@ -33,7 +33,7 @@  test01()
   // basic_string_view()
   const std::experimental::wstring_view str00{};
   VERIFY( str00.length() == 0 );
-  VERIFY( str00.data() != nullptr );
+  VERIFY( str00.data() == nullptr );
 
   // basic_string_view(const char*)
   const wchar_t str_lit01[] = L"rodeo beach, marin";
@@ -54,11 +54,6 @@  test01()
   VERIFY( str05.length() == len_lit01 );
   VERIFY( str05.data() == str_lit01 );
 
-  //  basic_string_view(const wchar_t* s, std::size_t l)
-  std::experimental::wstring_view str06{nullptr, len_lit01};
-  VERIFY( str06.length() == 0 );
-  VERIFY( str06.data() != nullptr );
-
   // basic_string_view(basic_string& s)
   std::wstring istr07(10, L'z');
   std::experimental::wstring_view str07{istr07};
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/copy/char/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/copy/char/1.cc
index 25b2af1..d0f3e8d 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/operations/copy/char/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/copy/char/1.cc
@@ -1,6 +1,6 @@ 
 // { dg-options "-std=gnu++1y" }
 
-// Copyright (C) 2013 Free Software Foundation, Inc.
+// Copyright (C) 2013-2014 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -20,7 +20,6 @@ 
 // basic_string_view::copy
 
 #include <experimental/string_view>
-#include <stdexcept>
 #include <testsuite_hooks.h>
 
 bool
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/copy/wchar_t/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/copy/wchar_t/1.cc
index 0348e1f..bf3f14b 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/operations/copy/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/copy/wchar_t/1.cc
@@ -1,6 +1,6 @@ 
 // { dg-options "-std=gnu++1y" }
 
-// Copyright (C) 2013 Free Software Foundation, Inc.
+// Copyright (C) 2013-2014 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -20,7 +20,6 @@ 
 // basic_string_view::copy
 
 #include <experimental/string_view>
-#include <stdexcept>
 #include <testsuite_hooks.h>
 
 bool
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/data/char/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/data/char/1.cc
index be75de9..a344926 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/operations/data/char/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/data/char/1.cc
@@ -1,6 +1,6 @@ 
 // { dg-options "-std=gnu++1y" }
 
-// Copyright (C) 2013 Free Software Foundation, Inc.
+// Copyright (C) 2013-2014 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -29,10 +29,9 @@  test01()
 
   std::experimental::string_view empty;
 
-  // data() for size == 0 is non-NULL.
   VERIFY( empty.size() == 0 );
   const std::experimental::string_view::value_type* p = empty.data();
-  VERIFY( p );
+  VERIFY( p == nullptr );
 
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/data/wchar_t/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/data/wchar_t/1.cc
index 5e00b00..41d2d14 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/operations/data/wchar_t/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/data/wchar_t/1.cc
@@ -1,6 +1,6 @@ 
 // { dg-options "-std=gnu++1y" }
 
-// Copyright (C) 2013 Free Software Foundation, Inc.
+// Copyright (C) 2013-2014 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -29,10 +29,9 @@  test01()
 
   std::experimental::wstring_view empty;
 
-  // data() for size == 0 is non-NULL.
   VERIFY( empty.size() == 0 );
   const std::experimental::wstring_view::value_type* p = empty.data();
-  VERIFY( p );
+  VERIFY( p == nullptr );
 
   return 0;
 }
diff --git a/libstdc++-v3/testsuite/experimental/string_view/operations/to_string/1.cc b/libstdc++-v3/testsuite/experimental/string_view/operations/to_string/1.cc
new file mode 100644
index 0000000..c0a5734
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/string_view/operations/to_string/1.cc
@@ -0,0 +1,53 @@ 
+// { dg-options "-std=gnu++1y" }
+
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// basic_string_view::to_string
+
+#include <experimental/string_view>
+#include <algorithm>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+bool
+test01()
+{
+  bool test [[gnu::unused]] = true;
+
+  const char str_lit[] = "123456789A";
+  const std::experimental::string_view sv(str_lit);
+  char buffer[4] = { 0 };
+
+  auto s1 = sv.to_string();
+  VERIFY( s1 == str_lit );
+  using test_alloc = __gnu_test::tracker_allocator<char>;
+  auto s2 = sv.to_string( test_alloc{} );
+  static_assert( std::is_same<decltype(s2)::allocator_type, test_alloc>::value,
+                 "to_string() uses custom allocator" );
+  VERIFY( std::equal(s1.begin(), s1.end(), s2.begin(), s2.end()) );
+  auto s3 = static_cast<std::string>(sv);
+  VERIFY( s3 == s1 );
+
+  return test;
+}
+
+int
+main()
+{
+  test01();
+}