diff options
author | Ville Voutilainen <ville.voutilainen@gmail.com> | 2017-01-11 13:23:43 +0200 |
---|---|---|
committer | Ville Voutilainen <ville@gcc.gnu.org> | 2017-01-11 13:23:43 +0200 |
commit | f3df0b3cde2476f77059e4c3a704ab1960fa883a (patch) | |
tree | 8e92072dbc8ee05ff40976301839998c89081a90 | |
parent | 51020892466d37f71ee13137bdadcbb32545c55d (diff) | |
download | gcc-f3df0b3cde2476f77059e4c3a704ab1960fa883a.zip gcc-f3df0b3cde2476f77059e4c3a704ab1960fa883a.tar.gz gcc-f3df0b3cde2476f77059e4c3a704ab1960fa883a.tar.bz2 |
Reduce the size of variant, it doesn't need an index of type size_t internally.
Reduce the size of variant, it doesn't need an index of
type size_t internally.
* include/std/variant (parse_numbers.h): New include.
(__select_index): New.
(_Variant_storage<false, _Types...>::_M_reset_impl): Use
_index_type for comparison with variant_npos.
(_Variant_storage<false, _Types...>::__index_type): New.
(_Variant_storage<false, _Types...>::_M_index): Change the
type from size_t to __index_type.
(_Variant_storage<true, _Types...>::__index_type): New.
(_Variant_storage<true, _Types...>::_M_index): Change the
type from size_t to __index_type.
(_Variant_base::_M_valid): Use _Storage::__index_type
for comparison with variant_npos.
(variant::index): Use _Base::_Storage::__index_type
for comparison with variant_npos.
* testsuite/20_util/variant/index_type.cc: New.
From-SVN: r244309
-rw-r--r-- | libstdc++-v3/ChangeLog | 20 | ||||
-rw-r--r-- | libstdc++-v3/include/std/variant | 28 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/variant/index_type.cc | 24 |
3 files changed, 67 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e3101e1..82e6ef6 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2017-01-11 Ville Voutilainen <ville.voutilainen@gmail.com> + + Reduce the size of variant, it doesn't need an index of + type size_t internally. + * include/std/variant (parse_numbers.h): New include. + (__select_index): New. + (_Variant_storage<false, _Types...>::_M_reset_impl): Use + _index_type for comparison with variant_npos. + (_Variant_storage<false, _Types...>::__index_type): New. + (_Variant_storage<false, _Types...>::_M_index): Change the + type from size_t to __index_type. + (_Variant_storage<true, _Types...>::__index_type): New. + (_Variant_storage<true, _Types...>::_M_index): Change the + type from size_t to __index_type. + (_Variant_base::_M_valid): Use _Storage::__index_type + for comparison with variant_npos. + (variant::index): Use _Base::_Storage::__index_type + for comparison with variant_npos. + * testsuite/20_util/variant/index_type.cc: New. + 2017-01-10 Jonathan Wakely <jwakely@redhat.com> * testsuite/18_support/exception_ptr/60612-unexpected.cc: Adjust diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 3d025a7..6404fce 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -43,6 +43,7 @@ #include <bits/functional_hash.h> #include <bits/invoke.h> #include <ext/aligned_buffer.h> +#include <bits/parse_numbers.h> namespace std _GLIBCXX_VISIBILITY(default) { @@ -314,6 +315,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<bool __trivially_destructible, typename... _Types> struct _Variant_storage; + template <typename... _Types> + using __select_index = + typename __select_int::_Select_int_base<sizeof...(_Types)+1, + unsigned char, + unsigned short> + ::type::value_type; + template<typename... _Types> struct _Variant_storage<false, _Types...> { @@ -332,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<size_t... __indices> constexpr void _M_reset_impl(std::index_sequence<__indices...>) { - if (_M_index != variant_npos) + if (_M_index != __index_type(variant_npos)) _S_vtable<__indices...>[_M_index](*this); } @@ -346,7 +354,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _M_reset(); } _Variadic_union<_Types...> _M_u; - size_t _M_index; + using __index_type = __select_index<_Types...>; + __index_type _M_index; }; template<typename... _Types> @@ -364,7 +373,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { _M_index = variant_npos; } _Variadic_union<_Types...> _M_u; - size_t _M_index; + using __index_type = __select_index<_Types...>; + __index_type _M_index; }; // Helps SFINAE on special member functions. Otherwise it can live in variant @@ -487,7 +497,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr bool _M_valid() const noexcept - { return this->_M_index != variant_npos; } + { + return this->_M_index != + typename _Storage::__index_type(variant_npos); + } }; // For how many times does _Tp appear in _Tuple? @@ -1086,7 +1099,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return !this->_M_valid(); } constexpr size_t index() const noexcept - { return this->_M_index; } + { + if (this->_M_index == + typename _Base::_Storage::__index_type(variant_npos)) + return variant_npos; + return this->_M_index; + } void swap(variant& __rhs) diff --git a/libstdc++-v3/testsuite/20_util/variant/index_type.cc b/libstdc++-v3/testsuite/20_util/variant/index_type.cc new file mode 100644 index 0000000..e6d3dda --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/variant/index_type.cc @@ -0,0 +1,24 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile { target x86_64-*-* powerpc*-*-* } } + +// Copyright (C) 2017 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 <variant> + +static_assert(sizeof(std::variant<signed char, unsigned char>) + < sizeof(size_t)); |