diff mbox

Update std::experimental::{any,optional,string_view}

Message ID 20141213204439.GT3134@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely Dec. 13, 2014, 8:44 p.m. UTC
This updates the Library Fundamentals types to reflect the changes
approved in Urbana.

Tested x86_64-linux, committed to trunk.
diff mbox

Patch

commit de8bfae1fd96f002edc115ddeb2cb4e28c6164ce
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Dec 12 22:28:57 2014 +0000

    Post-Urbana updates to Library Fundamentals v1.
    
    	* include/experimental/any (any): Remove allocator support and update
    	feature-testing macro.
    	* include/experimental/functional: Update feature-testing macro.
    	* include/experimental/optional (optional::_M_get()): Add constexpr.
    	(optional::operator*(), optional::value()): Overload and add
    	ref-qualifiers. Update feature-testing macro.
    	* include/experimental/string_view (basic_string_view::clear): Remove
    	and update feature-testing macro.
    	* testsuite/experimental/any/cons/3.cc: Remove.
    	* testsuite/experimental/any/cons/4.cc: Remove.
    	* testsuite/experimental/any/misc/any_cast.cc: Remove allocator tests.
    	* testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error.
    	* testsuite/experimental/string_view/capacity/1.cc: Don't test clear().

diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any
index 87dd7a1..3af925f 100644
--- a/libstdc++-v3/include/experimental/any
+++ b/libstdc++-v3/include/experimental/any
@@ -36,11 +36,9 @@ 
 #else
 
 #include <typeinfo>
-#include <memory>
+#include <new>
 #include <utility>
 #include <type_traits>
-#include <bits/alloc_traits.h>
-#include <bits/uses_allocator.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -60,7 +58,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @{
    */
 
-#define __cpp_lib_experimental_any 201402
+#define __cpp_lib_experimental_any 201411
 
   /**
    *  @brief Exception class thrown by a failed @c any_cast
@@ -96,7 +94,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::aligned_storage<sizeof(_M_ptr), sizeof(_M_ptr)>::type _M_buffer;
     };
 
-    template<typename _Tp, typename _Safe = is_nothrow_copy_constructible<_Tp>,
+    template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
 	     bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))>
       using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
 
@@ -111,19 +109,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				     _Manager_internal<_Tp>,
 				     _Manager_external<_Tp>>;
 
-#if __cpp_rtti
-    // When RTTI is disabled __any_caster assumes the manager is either
-    // _Manager_internal or _Manager_external, so this type must not be used.
-    template<typename _Tp, typename _Alloc>
-      struct _Manager_alloc; // creates contained object using an allocator
-
-    template<typename _Tp, typename _Alloc,
-	     typename _TpAlloc = __alloc_rebind<_Alloc, _Tp>>
-      using _ManagerAlloc = conditional_t<_Internal<_Tp>::value,
-					  _Manager_internal<_Tp>,
-					  _Manager_alloc<_Tp, _TpAlloc>>;
-#endif
-
     template<typename _Tp, typename _Decayed = decay_t<_Tp>>
       using _Decay = enable_if_t<!is_same<_Decayed, any>::value, _Decayed>;
 
@@ -165,35 +150,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 		      "The contained object must be CopyConstructible");
       }
 
-    /// Allocator-extended default constructor (the allocator is ignored).
-    template <typename _Allocator>
-      any(allocator_arg_t, const _Allocator&) noexcept : any() { }
-
-#if __cpp_rtti
-    /// Construct with a copy of @p __value as the contained object.
-    template <typename _Allocator, typename _ValueType,
-	      typename _Tp = _Decay<_ValueType>,
-	      typename _Mgr = _ManagerAlloc<_Tp, _Allocator>>
-      any(allocator_arg_t, const _Allocator& __a, _ValueType&& __value)
-      : _M_manager(&_Mgr::_S_manage),
-        _M_storage(_Mgr::_S_alloc(__a, std::forward<_ValueType>(__value)))
-      {
-	static_assert(is_copy_constructible<_Tp>::value,
-		      "The contained object must be CopyConstructible");
-      }
-#endif
-
-    /* TODO: implement this somehow
-    /// Allocator-extended copy constructor.
-    template <class _Allocator>
-      any(allocator_arg_t, const _Allocator& __a, const any& __other);
-    */
-
-    /// Allocator-extended move constructor (the allocator is ignored).
-    template <typename _Allocator>
-      any(allocator_arg_t, const _Allocator&, any&& __other) noexcept
-      : any(std::move(__other)) { }
-
     /// Destructor, calls @c clear()
     ~any() { clear(); }
 
@@ -281,13 +237,8 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     template<typename _Tp>
       friend void* __any_caster(const any* __any)
       {
-#if __cpp_rtti
-	if (__any->type() != typeid(_Tp))
-	  return nullptr;
-#else
 	if (__any->_M_manager != &_Manager<decay_t<_Tp>>::_S_manage)
 	  return nullptr;
-#endif
 	_Arg __arg;
 	__any->_M_manager(_Op_access, __any, &__arg);
 	return __arg._M_obj;
@@ -334,29 +285,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    return __storage;
 	  }
       };
-
-#if __cpp_rtti
-    // Manage external contained object using an allocator
-    template<typename _Tp, typename _Alloc>
-      struct _Manager_alloc
-      {
-	static_assert(std::is_same<_Tp, typename _Alloc::value_type>::value,
-		      "Allocator's value_type is correct");
-
-	// Type that holds contained object and allocator
-	struct _Data;
-
-	using _Traits = typename std::allocator_traits<_Alloc>::template
-	  rebind_traits<_Data>;
-
-	static void
-	_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
-
-	template<typename _Up>
-	  static _Storage
-	  _S_alloc(const _Alloc& __a, _Up&& __value);
-      };
-#endif
   };
 
   /// Exchange the states of two @c any objects.
@@ -446,71 +374,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
   // @}
 
-#if __cpp_rtti
-  template<typename _Tp, typename _Alloc>
-    struct any::_Manager_alloc<_Tp, _Alloc>::_Data
-    {
-      using _Traits = std::allocator_traits<_Alloc>;
-
-      std::tuple<__gnu_cxx::__aligned_buffer<_Tp>, _Alloc> _M_data;
-
-      _Alloc&       _M_alloc()       { return std::get<1>(_M_data); }
-      const _Alloc& _M_alloc() const { return std::get<1>(_M_data); }
-
-      _Tp*       _M_obj()       { return std::get<0>(_M_data)._M_ptr(); }
-      const _Tp* _M_obj() const { return std::get<0>(_M_data)._M_ptr(); }
-
-      template<typename _Up>
-	_Data(const _Alloc& __a, _Up&& __val) : _M_data(nullptr, __a)
-	{
-	  this->_M_construct(std::__use_alloc<_Tp, _Alloc, _Up&&>(_M_alloc()),
-			     std::forward<_Up>(__val));
-	}
-
-      ~_Data() { _Traits::destroy(_M_alloc(), _M_obj()); }
-
-      template<typename _Up>
-	void
-	_M_construct(__uses_alloc0, _Up&& __val)
-	{
-	  _Traits::construct(_M_alloc(), _M_obj(),
-			     std::forward<_Up>(__val));
-	}
-
-      template<typename _Up>
-	void
-	_M_construct(__uses_alloc1<_Alloc> __a, _Up&& __val)
-	{
-	  _Traits::construct(_M_alloc(), _M_obj(),
-			     std::allocator_arg, *__a._M_a,
-			     std::forward<_Up>(__val));
-	}
-
-      template<typename _Up>
-	void
-	_M_construct(__uses_alloc2<_Alloc> __a, _Up&& __val)
-	{
-	  _Traits::construct(_M_alloc(), _M_obj(),
-			     std::forward<_Up>(__val), *__a._M_a);
-	}
-    };
-
-  template<typename _Tp, typename _Alloc>
-  template<typename _Up>
-    any::_Storage
-    any::_Manager_alloc<_Tp, _Alloc>::
-    _S_alloc(const _Alloc& __a, _Up&& __value)
-    {
-      typename _Traits::allocator_type __a2(__a);
-      auto __guard = std::__allocate_guarded(__a2);
-      any::_Storage __storage;
-      __storage._M_ptr = __guard.get();
-      ::new(__storage._M_ptr) _Data{__a, std::forward<_Up>(__value)};
-      __guard = nullptr;
-      return __storage;
-    }
-#endif
-
   template<typename _Tp>
     void
     any::_Manager_internal<_Tp>::
@@ -563,38 +426,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     }
 
-#if __cpp_rtti
-  template<typename _Tp, typename _Alloc>
-    void
-    any::_Manager_alloc<_Tp, _Alloc>::
-    _S_manage(_Op __which, const any* __any, _Arg* __arg)
-    {
-      // The contained object is at _M_storage._M_ptr->_M_obj()
-      auto __ptr = static_cast<const _Data*>(__any->_M_storage._M_ptr);
-      switch (__which)
-      {
-      case _Op_access:
-	__arg->_M_obj = const_cast<_Tp*>(__ptr->_M_obj());
-	break;
-      case _Op_get_type_info:
-	__arg->_M_typeinfo = &typeid(_Tp);
-	break;
-      case _Op_clone:
-	__arg->_M_any->_M_storage
-	  = _S_alloc(__ptr->_M_alloc(), *__ptr->_M_obj());
-	break;
-      case _Op_destroy:
-	{
-	  using _Alloc2 = typename _Traits::allocator_type;
-	  _Alloc2 __a(__ptr->_M_alloc());
-	  __allocated_ptr<_Alloc2> __guard{__a, const_cast<_Data*>(__ptr)};
-	  __ptr->~_Data();
-	}
-	break;
-      }
-    }
-#endif
-
   // @} group any
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace fundamentals_v1
diff --git a/libstdc++-v3/include/experimental/functional b/libstdc++-v3/include/experimental/functional
index 4ecc6a5..5202e89 100644
--- a/libstdc++-v3/include/experimental/functional
+++ b/libstdc++-v3/include/experimental/functional
@@ -61,7 +61,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Tp>
     constexpr int is_placeholder_v = std::is_placeholder<_Tp>::value;
 
-#define __cpp_lib_experimental_boyer_moore_searching 201402
+#define __cpp_lib_experimental_boyer_moore_searching 201411
 
   // Searchers
 
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index 2d3127a..e87a1d4 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -67,7 +67,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * @{
    */
 
-#define __cpp_lib_experimental_optional 201406
+#define __cpp_lib_experimental_optional 201411
 
   // All subsequent [X.Y.n] references are against n3793.
 
@@ -290,7 +290,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return this->_M_engaged; }
 
       // The _M_get operations have _M_engaged as a precondition.
-      _Tp&
+      constexpr _Tp&
       _M_get() noexcept
       { return _M_payload; }
 
@@ -574,18 +574,26 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return std::__addressof(this->_M_get()); }
 
       constexpr const _Tp&
-      operator*() const
+      operator*() const&
       { return this->_M_get(); }
 
-      _Tp&
-      operator*()
+      constexpr _Tp&
+      operator*()&
       { return this->_M_get(); }
 
+      constexpr _Tp&&
+      operator*()&&
+      { return std::move(this->_M_get()); }
+
+      constexpr const _Tp&&
+      operator*() const&&
+      { return std::move(this->_M_get()); }
+
       constexpr explicit operator bool() const noexcept
       { return this->_M_is_engaged(); }
 
       constexpr const _Tp&
-      value() const
+      value() const&
       {
 	return this->_M_is_engaged()
 	  ?  this->_M_get()
@@ -594,14 +602,34 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	     this->_M_get());
       }
 
-      _Tp&
-      value()
+      constexpr _Tp&
+      value()&
       {
-        if (this->_M_is_engaged())
-          return this->_M_get();
+	return this->_M_is_engaged()
+	  ?  this->_M_get()
+	  : (__throw_bad_optional_access("Attempt to access value of a "
+		                         "disengaged optional object"),
+	     this->_M_get());
+      }
 
-        __throw_bad_optional_access("Attempt to access value of a "
-				    "disengaged optional object");
+      constexpr _Tp&&
+      value()&&
+      {
+	return this->_M_is_engaged()
+	  ?  std::move(this->_M_get())
+	  : (__throw_bad_optional_access("Attempt to access value of a "
+		                         "disengaged optional object"),
+	     std::move(this->_M_get()));
+      }
+
+      constexpr const _Tp&&
+      value() const&&
+      {
+	return this->_M_is_engaged()
+	  ?  std::move(this->_M_get())
+	  : (__throw_bad_optional_access("Attempt to access value of a "
+		                         "disengaged optional object"),
+	     std::move(this->_M_get()));
       }
 
       template<typename _Up>
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index 320d72d..6e1dd5a 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -50,7 +50,7 @@  inline namespace fundamentals_v1
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-#define __cpp_lib_experimental_string_view 201402
+#define __cpp_lib_experimental_string_view 201411
 
   /**
    *  @class basic_string_view <experimental/string_view>
@@ -219,13 +219,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // [string.view.modifiers], modifiers:
 
       void
-      clear() noexcept
-      {
-	this->_M_len = 0;
-	this->_M_str = nullptr;
-      }
-
-      void
       remove_prefix(size_type __n)
       {
 	_GLIBCXX_DEBUG_ASSERT(this->_M_len >= __n);
diff --git a/libstdc++-v3/testsuite/experimental/any/cons/3.cc b/libstdc++-v3/testsuite/experimental/any/cons/3.cc
deleted file mode 100644
index 671a178..0000000
--- a/libstdc++-v3/testsuite/experimental/any/cons/3.cc
+++ /dev/null
@@ -1,83 +0,0 @@ 
-// { dg-options "-std=gnu++14" }
-// { dg-do run }
-
-// 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/>.
-
-#include <experimental/any>
-#include <testsuite_allocator.h>
-
-using std::experimental::any;
-using __gnu_test::CustomPointerAlloc;
-using __gnu_test::tracker_allocator;
-using __gnu_test::tracker_allocator_counter;
-
-struct NotSmall { char c[64]; };
-
-bool test [[gnu::unused]] = true;
-
-void test01()
-{
-  CustomPointerAlloc<int> alloc;
-
-  any x(std::allocator_arg, alloc, 1);
-  VERIFY( !x.empty() );
-
-  any y(std::allocator_arg, alloc, std::move(x));
-  VERIFY( x.empty() );
-  VERIFY( !y.empty() );
-}
-
-void test02()
-{
-  tracker_allocator<int> alloc;
-
-  any x(std::allocator_arg, alloc, 1);
-  auto allocated = tracker_allocator_counter::get_allocation_count();
-  VERIFY( allocated == 0 );  // no allocation for small object
-
-  any y(std::allocator_arg, alloc, std::move(x));
-  VERIFY( tracker_allocator_counter::get_allocation_count() == 0 );
-
-  y = {};
-  VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 );
-}
-
-void test03()
-{
-  tracker_allocator<int> alloc;
-
-
-  any x(std::allocator_arg, alloc, NotSmall{});
-  auto allocated = tracker_allocator_counter::get_allocation_count();
-  __builtin_printf("ALLOCATED %lu\n", (unsigned long)allocated);
-  VERIFY( allocated >= sizeof(NotSmall) );
-
-  any y(std::allocator_arg, alloc, std::move(x));
-  VERIFY( tracker_allocator_counter::get_allocation_count() == allocated );
-
-  y = {};
-  VERIFY( tracker_allocator_counter::get_deallocation_count() == allocated );
-}
-
-
-int main()
-{
-  test01();
-  test02();
-  test03();
-}
diff --git a/libstdc++-v3/testsuite/experimental/any/cons/4.cc b/libstdc++-v3/testsuite/experimental/any/cons/4.cc
deleted file mode 100644
index 6e5e019..0000000
--- a/libstdc++-v3/testsuite/experimental/any/cons/4.cc
+++ /dev/null
@@ -1,73 +0,0 @@ 
-// { dg-options "-std=gnu++14" }
-// { dg-do run }
-
-// 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/>.
-
-#include <experimental/any>
-#include <memory>
-#include <testsuite_hooks.h>
-
-using std::experimental::any;
-
-struct NotSmall
-{
-  char c[64];  // prevent small-object optimization
-};
-
-struct T1
-{
-  using allocator_type = std::allocator<char>;
-
-  T1() = default;
-  T1(const T1&) : used_alloc(false) { }
-  T1(const T1&, const allocator_type&) : used_alloc(true) { }
-
-  bool used_alloc;
-
-  NotSmall x;
-};
-
-struct T2
-{
-  using allocator_type = std::allocator<char>;
-
-  T2() = default;
-  T2(const T2&) : used_alloc(false) { }
-  T2(std::allocator_arg_t, const allocator_type&, const T2&) : used_alloc(true)
-  { }
-
-  bool used_alloc;
-
-  NotSmall x;
-};
-
-bool test [[gnu::unused]] = true;
-
-void test01()
-{
-  any x1(std::allocator_arg, std::allocator<char>{}, T1{});
-  VERIFY( std::experimental::any_cast<T1&>(x1).used_alloc );
-
-  any x2(std::allocator_arg, std::allocator<char>{}, T2{});
-  VERIFY( std::experimental::any_cast<T2&>(x2).used_alloc );
-}
-
-int main()
-{
-  test01();
-}
diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
index 98de1bc6..edb67c3 100644
--- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
+++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc
@@ -77,32 +77,8 @@  void test02()
   }
 }
 
-void test03()
-{
-  using std::experimental::bad_any_cast;
-  any x(std::allocator_arg, std::allocator<double>{}, 1);
-  auto p = any_cast<double>(&x);
-  VERIFY(p == nullptr);
-
-  x = any(std::allocator_arg, std::allocator<int>{}, 1.0);
-  p = any_cast<double>(&x);
-  VERIFY(p != nullptr);
-
-  x = any(std::allocator_arg, std::allocator<char>{});
-  p = any_cast<double>(&x);
-  VERIFY(p == nullptr);
-
-  try {
-    any_cast<double>(x);
-    VERIFY(false);
-  } catch (const bad_any_cast&) {
-  }
-}
-
-
 int main()
 {
   test01();
   test02();
-  test03();
 }
diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
index 9ef7194..026acb0 100644
--- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc
@@ -26,5 +26,5 @@  void test01()
   using std::experimental::any_cast;
 
   const any y(1);
-  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 382 }
+  any_cast<int&>(y); // { dg-error "qualifiers" "" { target { *-*-* } } 310 }
 }
diff --git a/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc b/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc
index 5643311..1aa055e 100644
--- a/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc
+++ b/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc
@@ -133,7 +133,7 @@  test01()
   size_type_o sz03;
   size_type_o sz04;
 
-  // non-POD types: size, length, max_size, clear(), empty()
+  // non-POD types: size, length, max_size, empty()
   bool b01 = str02.empty();  
   VERIFY( b01 == true );
   sz03 = str02.size();
@@ -148,7 +148,7 @@  test01()
   VERIFY( sz03 >= sz04 );
 
   sz03 = str02.size();
-  str02.clear();  
+  str02 = {};
   b01 = str02.empty(); 
   VERIFY( b01 == true );
   sz04 = str02.size();