From f3df0b3cde2476f77059e4c3a704ab1960fa883a Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Wed, 11 Jan 2017 13:23:43 +0200 Subject: [PATCH] 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::_M_reset_impl): Use _index_type for comparison with variant_npos. (_Variant_storage::__index_type): New. (_Variant_storage::_M_index): Change the type from size_t to __index_type. (_Variant_storage::__index_type): New. (_Variant_storage::_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 --- libstdc++-v3/ChangeLog | 20 +++++++++++++ libstdc++-v3/include/std/variant | 28 +++++++++++++++---- .../testsuite/20_util/variant/index_type.cc | 24 ++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/variant/index_type.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index e3101e17468..82e6ef60f77 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,23 @@ +2017-01-11 Ville Voutilainen + + 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::_M_reset_impl): Use + _index_type for comparison with variant_npos. + (_Variant_storage::__index_type): New. + (_Variant_storage::_M_index): Change the + type from size_t to __index_type. + (_Variant_storage::__index_type): New. + (_Variant_storage::_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 * testsuite/18_support/exception_ptr/60612-unexpected.cc: Adjust diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant index 3d025a767d7..6404fceb02b 100644 --- a/libstdc++-v3/include/std/variant +++ b/libstdc++-v3/include/std/variant @@ -43,6 +43,7 @@ #include #include #include +#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -314,6 +315,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct _Variant_storage; + template + using __select_index = + typename __select_int::_Select_int_base + ::type::value_type; + template struct _Variant_storage { @@ -332,7 +340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template 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 @@ -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 00000000000..e6d3dda4069 --- /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 +// . + +#include + +static_assert(sizeof(std::variant) + < sizeof(size_t)); -- 2.30.2