+2014-12-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * 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().
+
2014-12-13 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/58594
#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)
{
* @{
*/
-#define __cpp_lib_experimental_any 201402
+#define __cpp_lib_experimental_any 201411
/**
* @brief Exception class thrown by a failed @c any_cast
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>;
_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>;
"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(); }
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;
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.
}
// @}
-#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>::
}
}
-#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
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
* @{
*/
-#define __cpp_lib_experimental_optional 201406
+#define __cpp_lib_experimental_optional 201411
// All subsequent [X.Y.n] references are against n3793.
{ return this->_M_engaged; }
// The _M_get operations have _M_engaged as a precondition.
- _Tp&
+ constexpr _Tp&
_M_get() noexcept
{ return _M_payload; }
{ 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()
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>
{
_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>
// [string.view.modifiers], modifiers:
- void
- clear() noexcept
- {
- this->_M_len = 0;
- this->_M_str = nullptr;
- }
-
void
remove_prefix(size_type __n)
{
+++ /dev/null
-// { 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();
-}
+++ /dev/null
-// { 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();
-}
}
}
-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();
}
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 }
}
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();
VERIFY( sz03 >= sz04 );
sz03 = str02.size();
- str02.clear();
+ str02 = {};
b01 = str02.empty();
VERIFY( b01 == true );
sz04 = str02.size();