aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2017-01-11 13:23:43 +0200
committerVille Voutilainen <ville@gcc.gnu.org>2017-01-11 13:23:43 +0200
commitf3df0b3cde2476f77059e4c3a704ab1960fa883a (patch)
tree8e92072dbc8ee05ff40976301839998c89081a90
parent51020892466d37f71ee13137bdadcbb32545c55d (diff)
downloadgcc-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/ChangeLog20
-rw-r--r--libstdc++-v3/include/std/variant28
-rw-r--r--libstdc++-v3/testsuite/20_util/variant/index_type.cc24
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));