diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index cb97b2779..ddef18250 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -638,7 +638,6 @@ set( libs/core/include/fcppt/cyclic_iterator_impl.hpp libs/core/include/fcppt/default_deleter.hpp libs/core/include/fcppt/default_deleter_fwd.hpp - libs/core/include/fcppt/detail/call_destructor.hpp libs/core/include/fcppt/detail/char_type.hpp libs/core/include/fcppt/detail/check_cpp.hpp libs/core/include/fcppt/detail/const.hpp @@ -652,7 +651,6 @@ set( libs/core/include/fcppt/detail/move_if_rvalue.hpp libs/core/include/fcppt/detail/move_iterator_if_rvalue.hpp libs/core/include/fcppt/detail/noncopyable.hpp - libs/core/include/fcppt/detail/placement_new.hpp libs/core/include/fcppt/detail/strong_typedef_cast.hpp libs/core/include/fcppt/detail/strong_typedef_tag.hpp libs/core/include/fcppt/detail/tag_type.hpp @@ -1443,19 +1441,16 @@ set( libs/core/include/fcppt/variant/compare.hpp libs/core/include/fcppt/variant/comparison.hpp libs/core/include/fcppt/variant/current_type_name.hpp - libs/core/include/fcppt/variant/detail/apply.hpp - libs/core/include/fcppt/variant/detail/assert_type.hpp libs/core/include/fcppt/variant/detail/disable_object.hpp libs/core/include/fcppt/variant/detail/get_exn_impl.hpp libs/core/include/fcppt/variant/detail/get_unsafe.hpp - libs/core/include/fcppt/variant/detail/index_of.hpp - libs/core/include/fcppt/variant/detail/nothrow_move_assignable.hpp - libs/core/include/fcppt/variant/detail/nothrow_move_constructible.hpp - libs/core/include/fcppt/variant/detail/type_info.hpp + libs/core/include/fcppt/variant/detail/get_unsafe_impl.hpp + libs/core/include/fcppt/variant/detail/has_type.hpp + libs/core/include/fcppt/variant/detail/std_type.hpp + libs/core/include/fcppt/variant/detail/std_type_impl.hpp libs/core/include/fcppt/variant/detail/types_of.hpp libs/core/include/fcppt/variant/dynamic_cast.hpp libs/core/include/fcppt/variant/dynamic_cast_types.hpp - libs/core/include/fcppt/variant/equal.hpp libs/core/include/fcppt/variant/exception.hpp libs/core/include/fcppt/variant/exception_fwd.hpp libs/core/include/fcppt/variant/get_exn.hpp @@ -1464,9 +1459,7 @@ set( libs/core/include/fcppt/variant/invalid_get.hpp libs/core/include/fcppt/variant/invalid_get_fwd.hpp libs/core/include/fcppt/variant/is_object.hpp - libs/core/include/fcppt/variant/less.hpp libs/core/include/fcppt/variant/match.hpp - libs/core/include/fcppt/variant/not_equal.hpp libs/core/include/fcppt/variant/object.hpp libs/core/include/fcppt/variant/object_decl.hpp libs/core/include/fcppt/variant/object_fwd.hpp diff --git a/libs/core/CMakeLists.txt b/libs/core/CMakeLists.txt index a24b0d51a..de4073f89 100644 --- a/libs/core/CMakeLists.txt +++ b/libs/core/CMakeLists.txt @@ -426,7 +426,6 @@ set( libs/core/include/fcppt/cyclic_iterator_impl.hpp libs/core/include/fcppt/default_deleter.hpp libs/core/include/fcppt/default_deleter_fwd.hpp - libs/core/include/fcppt/detail/call_destructor.hpp libs/core/include/fcppt/detail/char_type.hpp libs/core/include/fcppt/detail/check_cpp.hpp libs/core/include/fcppt/detail/const.hpp @@ -440,7 +439,6 @@ set( libs/core/include/fcppt/detail/move_if_rvalue.hpp libs/core/include/fcppt/detail/move_iterator_if_rvalue.hpp libs/core/include/fcppt/detail/noncopyable.hpp - libs/core/include/fcppt/detail/placement_new.hpp libs/core/include/fcppt/detail/strong_typedef_cast.hpp libs/core/include/fcppt/detail/strong_typedef_tag.hpp libs/core/include/fcppt/detail/tag_type.hpp @@ -1231,19 +1229,16 @@ set( libs/core/include/fcppt/variant/compare.hpp libs/core/include/fcppt/variant/comparison.hpp libs/core/include/fcppt/variant/current_type_name.hpp - libs/core/include/fcppt/variant/detail/apply.hpp - libs/core/include/fcppt/variant/detail/assert_type.hpp libs/core/include/fcppt/variant/detail/disable_object.hpp libs/core/include/fcppt/variant/detail/get_exn_impl.hpp libs/core/include/fcppt/variant/detail/get_unsafe.hpp - libs/core/include/fcppt/variant/detail/index_of.hpp - libs/core/include/fcppt/variant/detail/nothrow_move_assignable.hpp - libs/core/include/fcppt/variant/detail/nothrow_move_constructible.hpp - libs/core/include/fcppt/variant/detail/type_info.hpp + libs/core/include/fcppt/variant/detail/get_unsafe_impl.hpp + libs/core/include/fcppt/variant/detail/has_type.hpp + libs/core/include/fcppt/variant/detail/std_type.hpp + libs/core/include/fcppt/variant/detail/std_type_impl.hpp libs/core/include/fcppt/variant/detail/types_of.hpp libs/core/include/fcppt/variant/dynamic_cast.hpp libs/core/include/fcppt/variant/dynamic_cast_types.hpp - libs/core/include/fcppt/variant/equal.hpp libs/core/include/fcppt/variant/exception.hpp libs/core/include/fcppt/variant/exception_fwd.hpp libs/core/include/fcppt/variant/get_exn.hpp @@ -1252,9 +1247,7 @@ set( libs/core/include/fcppt/variant/invalid_get.hpp libs/core/include/fcppt/variant/invalid_get_fwd.hpp libs/core/include/fcppt/variant/is_object.hpp - libs/core/include/fcppt/variant/less.hpp libs/core/include/fcppt/variant/match.hpp - libs/core/include/fcppt/variant/not_equal.hpp libs/core/include/fcppt/variant/object.hpp libs/core/include/fcppt/variant/object_decl.hpp libs/core/include/fcppt/variant/object_fwd.hpp diff --git a/libs/core/include/fcppt/detail/placement_new.hpp b/libs/core/include/fcppt/detail/placement_new.hpp deleted file mode 100644 index 1ab2686a4..000000000 --- a/libs/core/include/fcppt/detail/placement_new.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_DETAIL_PLACEMENT_NEW_HPP_INCLUDED -#define FCPPT_DETAIL_PLACEMENT_NEW_HPP_INCLUDED - -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace detail -{ - -template< - typename Type -> -inline -void -placement_new( - void *const _store, - Type &&_value -) -{ - new ( - _store - ) - fcppt::type_traits::remove_cv_ref_t< - Type - >( - std::forward< - Type - >( - _value - ) - ); -} - -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/apply.hpp b/libs/core/include/fcppt/variant/apply.hpp index 3c57b1bb8..00306ee22 100644 --- a/libs/core/include/fcppt/variant/apply.hpp +++ b/libs/core/include/fcppt/variant/apply.hpp @@ -7,20 +7,14 @@ #ifndef FCPPT_VARIANT_APPLY_HPP_INCLUDED #define FCPPT_VARIANT_APPLY_HPP_INCLUDED -#include #include #include #include -#include -#include -#include #include #include -#include #include #include -#include -#include +#include #include @@ -56,34 +50,12 @@ apply( ); return - fcppt::variant::detail::apply( + std::visit( _function, - &fcppt::absurd< - decltype( - _function( - fcppt::move_if_rvalue< - Variants - >( - fcppt::variant::detail::get_unsafe< - ::brigand::front< - fcppt::variant::types_of< - fcppt::type_traits::remove_cv_ref_t< - Variants - > - > - > - >( - _variants - ) - )... - ) - ) - >, - std::tuple<>{}, - std::forward< + fcppt::move_if_rvalue< Variants >( - _variants + _variants.impl() )... ); } diff --git a/libs/core/include/fcppt/variant/comparison.hpp b/libs/core/include/fcppt/variant/comparison.hpp index 4d99bb644..e5075d114 100644 --- a/libs/core/include/fcppt/variant/comparison.hpp +++ b/libs/core/include/fcppt/variant/comparison.hpp @@ -7,8 +7,99 @@ #ifndef FCPPT_VARIANT_COMPARISON_HPP_INCLUDED #define FCPPT_VARIANT_COMPARISON_HPP_INCLUDED -#include -#include +#include +namespace fcppt +{ +namespace variant +{ + +/** +\brief Compares two variants for equality + +\ingroup fcpptvariant + +Compares \a _left and \a _right for equality. The two variants are equal if they hold +the same type and the values compare equal. This function requires all possible +types of the variant to be equality comparable. +*/ +template< + typename Types +> +bool +operator==( + fcppt::variant::object< + Types + > const &_left, + fcppt::variant::object< + Types + > const &_right +) +{ + return + _left.impl() + == + _right.impl(); +} + +/** +\brief Compares two variants for inequality + +\ingroup fcpptvariant + +Compares \a _a and \a _b for inequality. Equal to !(_a == _b). +This function requires all possible types of the variant to be equality +comparable. +*/ +template< + typename Types +> +bool +operator!=( + fcppt::variant::object< + Types + > const &_a, + fcppt::variant::object< + Types + > const &_b +) +{ + return + !(_a == _b); +} + +/** +\brief Tests if one variant is less than another + +\ingroup fcpptvariant + +Tests if \a _left is less than \a _right. Let val_left be the value stored in +\a _left and val_right the value stored in \a _right. \a _left is less than \a +_right iff (_left.type_index(), val_left) is lexicographically +before (_right.type_index(), val_right). This also implies that +every type of the variant must be less comparable. +*/ +template< + typename Types +> +bool +operator<( + fcppt::variant::object< + Types + > const &_left, + fcppt::variant::object< + Types + > const &_right +) +{ + return + _left.impl() + < + _right.impl(); +} + +} +} + #endif diff --git a/libs/core/include/fcppt/variant/current_type_name.hpp b/libs/core/include/fcppt/variant/current_type_name.hpp index f13fac8ad..a675f1d0f 100644 --- a/libs/core/include/fcppt/variant/current_type_name.hpp +++ b/libs/core/include/fcppt/variant/current_type_name.hpp @@ -8,12 +8,10 @@ #define FCPPT_VARIANT_CURRENT_TYPE_NAME_HPP_INCLUDED #include -#include -#include #include +#include #include #include -#include #include @@ -38,23 +36,10 @@ current_type_name( ) { return - fcppt::variant::apply( - []( - auto const &_element + fcppt::type_name_from_index( + fcppt::variant::type_info( + _variant ) - { - FCPPT_USE( - _element - ); - - return - fcppt::type_name_from_index( - typeid( - _element - ) - ); - }, - _variant ); } diff --git a/libs/core/include/fcppt/variant/detail/apply.hpp b/libs/core/include/fcppt/variant/detail/apply.hpp deleted file mode 100644 index a57ac96fe..000000000 --- a/libs/core/include/fcppt/variant/detail/apply.hpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_DETAIL_APPLY_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_APPLY_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ -namespace detail -{ - -FCPPT_PP_PUSH_WARNING -FCPPT_PP_DISABLE_VC_WARNING(4702) - -template< - typename Function, - typename FailFunction, - typename... Args -> -decltype( - auto -) -apply( - Function const &_function, - FailFunction const &, - std::tuple< - Args... - > &&_tuple -) -{ - return - fcppt::container::tuple::to_varargs( - std::move( - _tuple - ), - [ - &_function - ]( - auto &&... _inner_args - ) - -> - decltype( - auto - ) - { - return - _function( - std::forward< - decltype( - _inner_args - ) - >( - _inner_args - )... - ); - } - ); -} - -template< - typename Function, - typename FailFunction, - typename... Args, - typename Variant1, - typename... Variants -> -decltype( - auto -) -apply( - Function const &_function, - FailFunction const &_fail_function, - std::tuple< - Args... - > &&_args, - Variant1 &&_variant1, - Variants &&... _variants -) -{ - return - fcppt::brigand::invoke_on< - fcppt::variant::types_of< - fcppt::type_traits::remove_cv_ref_t< - Variant1 - > - > - >( - _variant1.type_index(), - [ - &_function, - &_args, - &_fail_function, - &_variant1, - &_variants... - ]( - auto const _type - ) - -> - decltype( - auto - ) - { - FCPPT_USE( - _type - ); - - return - fcppt::variant::detail::apply( - _function, - _fail_function, - std::tuple_cat( - std::move( - _args - ), - std::forward_as_tuple( - fcppt::move_if_rvalue< - Variant1 - >( - fcppt::variant::detail::get_unsafe< - fcppt::tag_type< - decltype( - _type - ) - > - >( - _variant1 - ) - ) - ) - ), - std::forward< - Variants - >( - _variants - )... - ); - }, - _fail_function - ); -} - -FCPPT_PP_POP_WARNING - -} -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/detail/assert_type.hpp b/libs/core/include/fcppt/variant/detail/assert_type.hpp deleted file mode 100644 index b78bb3440..000000000 --- a/libs/core/include/fcppt/variant/detail/assert_type.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_DETAIL_ASSERT_TYPE_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_ASSERT_TYPE_HPP_INCLUDED - -#include -#include -#include -#include - - -#define FCPPT_VARIANT_DETAIL_ASSERT_TYPE(\ - types,\ - other,\ - elements\ -)\ -static_assert((\ - ::fcppt::variant::detail::index_of<\ - types,\ - std::remove_reference_t<\ - other\ - >\ - >::value\ - < elements\ - ),\ - "Invalid type given to a variant"\ -) - -#endif diff --git a/libs/core/include/fcppt/variant/detail/get_unsafe_impl.hpp b/libs/core/include/fcppt/variant/detail/get_unsafe_impl.hpp new file mode 100644 index 000000000..2f3176d38 --- /dev/null +++ b/libs/core/include/fcppt/variant/detail/get_unsafe_impl.hpp @@ -0,0 +1,61 @@ +// Copyright Carl Philipp Reh 2009 - 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef FCPPT_VARIANT_DETAIL_GET_UNSAFE_IMPL_HPP_INCLUDED +#define FCPPT_VARIANT_DETAIL_GET_UNSAFE_IMPL_HPP_INCLUDED + +#include +#include +#include +#include +#include + + +namespace fcppt +{ +namespace variant +{ +namespace detail +{ + +template< + typename Types, + typename U, + typename Variant +> +std::conditional_t< + std::is_const_v< + Variant + >, + U const &, + U & +> +get_unsafe_impl( + Variant &_variant +) +{ + static_assert( + fcppt::variant::detail::has_type< + Types, + U + >::value, + "Invalid variant type" + ); + + // TODO: Use get_if if we can get rid of gcc null-dereference warnings + return + std::get< + U + >( + _variant + ); +} + +} +} +} + +#endif diff --git a/libs/core/include/fcppt/detail/call_destructor.hpp b/libs/core/include/fcppt/variant/detail/has_type.hpp similarity index 53% rename from libs/core/include/fcppt/detail/call_destructor.hpp rename to libs/core/include/fcppt/variant/detail/has_type.hpp index 797a38c28..02a1ece87 100644 --- a/libs/core/include/fcppt/detail/call_destructor.hpp +++ b/libs/core/include/fcppt/variant/detail/has_type.hpp @@ -4,33 +4,32 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef FCPPT_DETAIL_CALL_DESTRUCTOR_HPP_INCLUDED -#define FCPPT_DETAIL_CALL_DESTRUCTOR_HPP_INCLUDED +#ifndef FCPPT_VARIANT_DETAIL_HAS_TYPE_HPP_INCLUDED +#define FCPPT_VARIANT_DETAIL_HAS_TYPE_HPP_INCLUDED -#include +#include namespace fcppt { +namespace variant +{ namespace detail { template< - typename Type + typename Types, + typename Element > -inline -void -call_destructor( - Type const &_value -) -{ - FCPPT_USE( - _value - ); +using +has_type += +fcppt::brigand::found_t< + Types, + Element +>; - _value.~Type(); } - } } diff --git a/libs/core/include/fcppt/variant/detail/index_of.hpp b/libs/core/include/fcppt/variant/detail/index_of.hpp deleted file mode 100644 index bdf799f68..000000000 --- a/libs/core/include/fcppt/variant/detail/index_of.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_DETAIL_INDEX_OF_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_INDEX_OF_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ -namespace detail -{ - -template< - typename Types, - typename Element -> -using index_of -= -fcppt::brigand::integral_cast< - fcppt::variant::size_type, - fcppt::cast::static_cast_fun, - ::brigand::index_of< - Types, - Element - > ->; - -} -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/detail/nothrow_move_assignable.hpp b/libs/core/include/fcppt/variant/detail/nothrow_move_assignable.hpp deleted file mode 100644 index 4f9fd7a2c..000000000 --- a/libs/core/include/fcppt/variant/detail/nothrow_move_assignable.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_DETAIL_NOTHROW_MOVE_ASSIGNABLE_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_NOTHROW_MOVE_ASSIGNABLE_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ -namespace detail -{ - -template< - typename Types -> -using -nothrow_move_assignable -= -::brigand::and_< - fcppt::variant::detail::nothrow_move_constructible< - Types - >, - ::brigand::all< - Types, - std::is_nothrow_move_assignable< - ::brigand::_1 - > - > ->; - -} -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/detail/nothrow_move_constructible.hpp b/libs/core/include/fcppt/variant/detail/nothrow_move_constructible.hpp deleted file mode 100644 index 68c9df4d0..000000000 --- a/libs/core/include/fcppt/variant/detail/nothrow_move_constructible.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_DETAIL_NOTHROW_MOVE_CONSTRUCTIBLE_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_NOTHROW_MOVE_CONSTRUCTIBLE_HPP_INCLUDED - -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ -namespace detail -{ - -template< - typename Types -> -using -nothrow_move_constructible -= -::brigand::all< - Types, - std::is_nothrow_move_constructible< - ::brigand::_1 - > ->; - -} -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/detail/std_type.hpp b/libs/core/include/fcppt/variant/detail/std_type.hpp new file mode 100644 index 000000000..62cbab35b --- /dev/null +++ b/libs/core/include/fcppt/variant/detail/std_type.hpp @@ -0,0 +1,35 @@ +// Copyright Carl Philipp Reh 2009 - 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + + +#ifndef FCPPT_VARIANT_DETAIL_STD_TYPE_HPP_INCLUDED +#define FCPPT_VARIANT_DETAIL_STD_TYPE_HPP_INCLUDED + +#include + + +namespace fcppt +{ +namespace variant +{ +namespace detail +{ + +template< + typename Types +> +using +std_type += +typename +fcppt::variant::detail::std_type_impl< + Types +>::type; + +} +} +} + +#endif diff --git a/libs/core/include/fcppt/variant/detail/type_info.hpp b/libs/core/include/fcppt/variant/detail/std_type_impl.hpp similarity index 52% rename from libs/core/include/fcppt/variant/detail/type_info.hpp rename to libs/core/include/fcppt/variant/detail/std_type_impl.hpp index b28d58dfb..bd18ba274 100644 --- a/libs/core/include/fcppt/variant/detail/type_info.hpp +++ b/libs/core/include/fcppt/variant/detail/std_type_impl.hpp @@ -4,11 +4,12 @@ // http://www.boost.org/LICENSE_1_0.txt) -#ifndef FCPPT_VARIANT_DETAIL_TYPE_INFO_HPP_INCLUDED -#define FCPPT_VARIANT_DETAIL_TYPE_INFO_HPP_INCLUDED +#ifndef FCPPT_VARIANT_DETAIL_STD_TYPE_IMPL_HPP_INCLUDED +#define FCPPT_VARIANT_DETAIL_STD_TYPE_IMPL_HPP_INCLUDED #include -#include +#include +#include #include @@ -19,20 +20,25 @@ namespace variant namespace detail { -struct type_info +template< + typename Type +> +struct std_type_impl; + +template< + typename... Types +> +struct std_type_impl< + ::brigand::list< + Types... + > +> { - typedef std::type_info const &result_type; - - template< - typename T + typedef + std::variant< + Types... > - result_type - operator()( - T const & - ) const - { - return typeid(T); - } + type; }; } diff --git a/libs/core/include/fcppt/variant/equal.hpp b/libs/core/include/fcppt/variant/equal.hpp deleted file mode 100644 index c04883213..000000000 --- a/libs/core/include/fcppt/variant/equal.hpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_EQUAL_HPP_INCLUDED -#define FCPPT_VARIANT_EQUAL_HPP_INCLUDED - -#include -#include -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ - -/** -\brief Compares two variants for equality - -\ingroup fcpptvariant - -Compares \a _left and \a _right for equality. The two variants are equal if they hold -the same type and the values compare equal. This function requires all possible -types of the variant to be equality comparable. - -\param _left The first variant -\param _right The second variant -*/ -template< - typename Types -> -bool -operator==( - fcppt::variant::object< - Types - > const &_left, - fcppt::variant::object< - Types - > const &_right -) -{ - return - fcppt::variant::apply( - [ - &_left - ]( - auto const &_right_inner - ) - -> bool - { - return - fcppt::optional::maybe( - fcppt::variant::to_optional< - fcppt::type_traits::remove_cv_ref_t< - decltype( - _right_inner - ) - > - >( - _left - ), - fcppt::const_( - false - ), - [ - &_right_inner - ]( - auto const &_left_inner - ) - { - return - _left_inner - == - _right_inner; - } - ); - }, - _right - ); -} - -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/holds_type.hpp b/libs/core/include/fcppt/variant/holds_type.hpp index 29231ddef..2905afb2a 100644 --- a/libs/core/include/fcppt/variant/holds_type.hpp +++ b/libs/core/include/fcppt/variant/holds_type.hpp @@ -8,13 +8,12 @@ #define FCPPT_VARIANT_HOLDS_TYPE_HPP_INCLUDED #include -#include -#include #include #include #include #include #include +#include #include @@ -69,12 +68,11 @@ holds_type( ); return - _variant.type_index() - == - fcppt::variant::detail::index_of< - Elements, + std::holds_alternative< Type - >::value; + >( + _variant.impl() + ); } } diff --git a/libs/core/include/fcppt/variant/less.hpp b/libs/core/include/fcppt/variant/less.hpp deleted file mode 100644 index a21457937..000000000 --- a/libs/core/include/fcppt/variant/less.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_LESS_HPP_INCLUDED -#define FCPPT_VARIANT_LESS_HPP_INCLUDED - -#include -#include -#include -#include - - -namespace fcppt -{ -namespace variant -{ - -/** -\brief Tests if one variant is less than another - -\ingroup fcpptvariant - -Tests if \a _left is less than \a _right. Let val_left be the value stored in -\a _left and val_right the value stored in \a _right. \a _left is less than \a -_right iff (_left.type_index(), val_left) is lexicographically -before (_right.type_index(), val_right). This also implies that -every type of the variant must be less comparable. - -\param _left The first variant -\param _right The second variant -*/ -template< - typename Types -> -bool -operator<( - fcppt::variant::object< - Types - > const &_left, - fcppt::variant::object< - Types - > const &_right -) -{ - return - _left.type_index() - == - _right.type_index() - ? - - fcppt::variant::apply( - [ - &_left - ]( - auto const &_right_inner - ){ - return - fcppt::variant::get_unsafe< - fcppt::type_traits::remove_cv_ref_t< - decltype( - _right_inner - ) - > - >( - _left - ) - < - _right_inner; - }, - _right - ) - : - _left.type_index() - < - _right.type_index() - ; -} - -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/not_equal.hpp b/libs/core/include/fcppt/variant/not_equal.hpp deleted file mode 100644 index e9cfa624a..000000000 --- a/libs/core/include/fcppt/variant/not_equal.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#ifndef FCPPT_VARIANT_NOT_EQUAL_HPP_INCLUDED -#define FCPPT_VARIANT_NOT_EQUAL_HPP_INCLUDED - -#include -#include - - -namespace fcppt -{ -namespace variant -{ - -/** -\brief Compares two variants for inequality - -\ingroup fcpptvariant - -Compares \a _a and \a _b for inequality. Equal to !(_a == _b). -This function requires all possible types of the variant to be equality -comparable. - -\param _a The first variant -\param _b The second variant -*/ -template< - typename Types -> -bool -operator!=( - fcppt::variant::object< - Types - > const &_a, - fcppt::variant::object< - Types - > const &_b -) -{ - return - !(_a == _b); -} - -} -} - -#endif diff --git a/libs/core/include/fcppt/variant/object_decl.hpp b/libs/core/include/fcppt/variant/object_decl.hpp index 436cbff0e..5b9a7ff98 100644 --- a/libs/core/include/fcppt/variant/object_decl.hpp +++ b/libs/core/include/fcppt/variant/object_decl.hpp @@ -7,20 +7,11 @@ #ifndef FCPPT_VARIANT_OBJECT_DECL_HPP_INCLUDED #define FCPPT_VARIANT_OBJECT_DECL_HPP_INCLUDED -#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace fcppt @@ -52,16 +43,22 @@ class object "Types must be a brigand sequence" ); + typedef + fcppt::variant::detail::std_type< + Types + > + std_type; + /** - \brief An mpl sequence of the possible types + \brief The brigand sequence of the possible types */ - typedef Types types; + typedef + Types + types; /** \brief Constructs the variant from a value - Constructs the variant from \a value. - \tparam U Must be a type among types */ template< @@ -69,7 +66,7 @@ class object > explicit object( - U const &value + U const & ); /** @@ -80,107 +77,18 @@ class object \tparam U Must be a type among types */ template< - typename U + typename U, + typename = + fcppt::variant::detail::disable_object< + U, + object + > > explicit object( - U &&value, - fcppt::variant::detail::disable_object< - U, - object - > * = nullptr - ); - - /** - \brief Copy constructs a variant - - Copy constructs the value held by \a other into the variant. - */ - object( - object const &other - ); - - /** - \brief Move constructs a variant - - Move constructs the value held by \a other into the variant. - */ - object( - object &&other - ) - noexcept( - fcppt::variant::detail::nothrow_move_constructible< - Types - >::value - ); - - /** - \brief Assigns a new value to the variant - - Assigns \a value to the variant. Calls the assignment operator of the - held type when possible. - - \tparam U Must be a type among types - */ - template< - typename U - > - object & - operator=( - U const &value - ); - - /** - \brief Move assigns a new value to the variant - - Move assigns \a value to the variant. Calls the move assignment - operator of the held type when possible. - */ - template< - typename U - > - fcppt::variant::detail::disable_object< - U, - object - > & - operator=( - U &&value - ); - - /** - \brief Assigns a variant - - Assigns the value from \a other to the variant. Calls the assignment - operator of the held type when possible. - */ - object & - operator=( - object const &other - ); - - /** - \brief Move assigns a variant - - Move assigns the value from \a other to the variant. Calls the - move assignment operator of the held type when possible. - */ - object & - operator=( - object &&other - ) - noexcept( - fcppt::variant::detail::nothrow_move_assignable< - Types - >::value + U && ); - /** - \brief Destroys the variant - - Calls the destructor of the held value. - */ - ~object(); - /** \brief Returns a const reference to the held type without any checks. @@ -225,67 +133,14 @@ class object */ bool is_invalid() const; -private: - template< - typename U - > - void - construct( - U const & - ); - template< - typename U - > - void - move_from( - U && - ); - - void - destroy(); - - void - swap_unequal( - object & - ); - - void * - raw_data(); - - void const * - raw_data() const; + std_type & + impl(); - static fcppt::variant::size_type const elements = - ::brigand::size< - Types - >::value - ; - - typedef - std::aligned_storage_t< - fcppt::brigand::max_value< - ::brigand::transform< - Types, - ::brigand::sizeof_< - ::brigand::_1 - > - > - >::value, - fcppt::brigand::max_value< - ::brigand::transform< - Types, - std::alignment_of< - ::brigand::_1 - > - > - >::value - > - storage_type; - - storage_type storage_; - - fcppt::variant::size_type index_; + std_type const & + impl() const; +private: + std_type impl_; }; } diff --git a/libs/core/include/fcppt/variant/object_impl.hpp b/libs/core/include/fcppt/variant/object_impl.hpp index b48f79666..5087b3817 100644 --- a/libs/core/include/fcppt/variant/object_impl.hpp +++ b/libs/core/include/fcppt/variant/object_impl.hpp @@ -7,25 +7,14 @@ #ifndef FCPPT_VARIANT_OBJECT_IMPL_HPP_INCLUDED #define FCPPT_VARIANT_OBJECT_IMPL_HPP_INCLUDED -#include -#include -#include -#include -#include -#include #include -#include #include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include #include +#include #include @@ -41,312 +30,47 @@ fcppt::variant::object< U const &_other ) : - storage_() - // Don't initialize index_ -{ - this->construct( + impl_{ _other - ); -} - -template< - typename Types -> -template< - typename U -> -fcppt::variant::object< - Types ->::object( - U &&_other, - fcppt::variant::detail::disable_object< - U, - object - > * -) -: - storage_() - // Don't initialize index_ + } { - this->move_from( - std::move( - _other - ) + static_assert( + fcppt::variant::detail::has_type< + Types, + U + >::value, + "Invalid variant type" ); } template< typename Types > -fcppt::variant::object< - Types ->::object( - object const &_other -) -: - storage_(), - index_( - _other.index_ - ) -{ - fcppt::variant::apply( - [ - this - ]( - auto const &_other_inner - ) - { - fcppt::detail::placement_new( - this->raw_data(), - _other_inner - ); - }, - _other - ); -} - template< - typename Types + typename U, + typename > fcppt::variant::object< Types >::object( - object &&_other -) -noexcept( - fcppt::variant::detail::nothrow_move_constructible< - Types - >::value + U &&_other ) : - storage_(), - index_( - _other.index_ - ) -{ - fcppt::variant::apply( - [ - this - ]( - auto &&_value - ) - { - fcppt::detail::placement_new( - this->raw_data(), - std::move( - _value - ) - ); - }, + impl_{ std::move( _other ) - ); -} - -template< - typename Types -> -template< - typename U -> -fcppt::variant::object< - Types -> & -fcppt::variant::object< - Types ->::operator=( - U const &_other -) -{ - if( - fcppt::variant::detail::index_of< - Types, - U - >::value - == - index_ - ) - this->template get_unsafe< - U - >() = - _other; - else - { - this->destroy(); - - this->construct( - _other - ); } - - return - *this; -} - -template< - typename Types -> -template< - typename U -> -fcppt::variant::detail::disable_object< - U, - fcppt::variant::object< - Types - > -> & -fcppt::variant::object< - Types ->::operator=( - U &&_other -) { - if( - fcppt::variant::detail::index_of< + static_assert( + fcppt::variant::detail::has_type< Types, - U - >::value - == - index_ - ) - this-> template get_unsafe< fcppt::type_traits::remove_cv_ref_t< U > - >() = - std::move( - _other - ); - else - { - this->destroy(); - - this->move_from( - std::move( - _other - ) - ); - } - - return - *this; -} - -template< - typename Types -> -fcppt::variant::object< - Types -> & -fcppt::variant::object< - Types ->::operator=( - object const &_other -) -{ - if( - index_ - == - _other.type_index() - ) - fcppt::variant::apply( - [ - this - ]( - auto const &_other_inner - ) - { - this-> template get_unsafe< - fcppt::type_traits::remove_cv_ref_t< - decltype( - _other_inner - ) - > - >() = - _other_inner; - }, - _other - ); - else - fcppt::variant::apply( - [ - this - ]( - auto const &_value - ) - { - *this = - _value; - }, - _other - ); - - return - *this; -} - -template< - typename Types -> -fcppt::variant::object< - Types -> & -fcppt::variant::object< - Types ->::operator=( - object &&_other -) -noexcept( - fcppt::variant::detail::nothrow_move_assignable< - Types - >::value -) -{ - if( - index_ - == - _other.type_index() - ) - fcppt::variant::apply( - [ - this - ]( - auto &&_other_inner - ) - { - this->template get_unsafe< - fcppt::type_traits::remove_cv_ref_t< - decltype( - _other_inner - ) - > - >() = - std::move( - _other_inner - ); - }, - std::move( - _other - ) - ); - else - this->swap_unequal( - _other - ); - - return - *this; -} - -template< - typename Types -> -fcppt::variant::object< - Types ->::~object() -{ - this->destroy(); + >::value, + "Invalid variant type" + ); } template< @@ -360,17 +84,12 @@ fcppt::variant::object< Types >::get_unsafe() { - FCPPT_VARIANT_DETAIL_ASSERT_TYPE( - Types, - U, - elements - ); - return - *fcppt::cast::from_void_ptr< - U * + fcppt::variant::detail::get_unsafe_impl< + Types, + U >( - this->raw_data() + this->impl_ ); } @@ -385,17 +104,12 @@ fcppt::variant::object< Types >::get_unsafe() const { - FCPPT_VARIANT_DETAIL_ASSERT_TYPE( - Types, - U, - elements - ); - return - *fcppt::cast::from_void_ptr< - U const * + fcppt::variant::detail::get_unsafe_impl< + Types, + U >( - this->raw_data() + this->impl_ ); } @@ -408,7 +122,7 @@ fcppt::variant::object< >::type_index() const { return - index_; + this->impl_.index(); } template< @@ -422,175 +136,37 @@ fcppt::variant::object< return this->type_index() == - elements; + std::variant_npos; } -FCPPT_PP_PUSH_WARNING -FCPPT_PP_DISABLE_VC_WARNING(4702) - template< typename Types > -template< - typename U -> -void +typename fcppt::variant::object< Types ->::construct( - U const &_other -) -{ - FCPPT_VARIANT_DETAIL_ASSERT_TYPE( - Types, - U, - elements - ); - - new ( - this->raw_data() - ) - U( - _other - ); - - index_ = - fcppt::variant::detail::index_of< - Types, - U - >::value; -} - -template< - typename Types -> -template< - typename U -> -void -fcppt::variant::object< - Types ->::move_from( - U &&_other -) -{ - FCPPT_VARIANT_DETAIL_ASSERT_TYPE( - Types, - U, - elements - ); - - new ( - this->raw_data() - ) - std::remove_reference_t< - U - >( - std::move( - _other - ) - ); - - index_ = - fcppt::variant::detail::index_of< - Types, - U - >::value; -} - -FCPPT_PP_POP_WARNING - -template< - typename Types -> -void -fcppt::variant::object< - Types ->::destroy() -{ - if( - this->is_invalid() - ) - return; - - fcppt::variant::apply( - []( - auto &_value - ) - { - fcppt::detail::call_destructor( - _value - ); - }, - *this - ); - - index_ = - elements; -} - -template< - typename Types -> -void +>::std_type & fcppt::variant::object< Types ->::swap_unequal( - object &_other -) +>::impl() { - fcppt::variant::apply( - [ - &_other, - this - ]( - auto &_left, - auto &_right - ) - { - auto temp( - std::move( - _left - ) - ); - - *this = - std::move( - _right - ); - - _other = - std::move( - temp - ); - }, - *this, - _other - ); + return + this->impl_; } template< typename Types > -void * +typename fcppt::variant::object< Types ->::raw_data() -{ - return - &storage_; -} - -template< - typename Types -> -void const * +>::std_type const & fcppt::variant::object< Types ->::raw_data() const +>::impl() const { return - &storage_; + this->impl_; } #endif diff --git a/libs/core/include/fcppt/variant/size_type.hpp b/libs/core/include/fcppt/variant/size_type.hpp index db044f304..47fd19f93 100644 --- a/libs/core/include/fcppt/variant/size_type.hpp +++ b/libs/core/include/fcppt/variant/size_type.hpp @@ -7,6 +7,10 @@ #ifndef FCPPT_VARIANT_SIZE_TYPE_HPP_INCLUDED #define FCPPT_VARIANT_SIZE_TYPE_HPP_INCLUDED +#include +#include +#include + namespace fcppt { @@ -20,7 +24,7 @@ namespace variant \see fcppt::variant::object::type_index */ -typedef unsigned size_type; +typedef std::size_t size_type; } } diff --git a/libs/core/include/fcppt/variant/to_optional.hpp b/libs/core/include/fcppt/variant/to_optional.hpp index 4a59eb6d6..b9b56e018 100644 --- a/libs/core/include/fcppt/variant/to_optional.hpp +++ b/libs/core/include/fcppt/variant/to_optional.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -51,9 +52,11 @@ to_optional( fcppt::move_if_rvalue< Variant >( - _variant. template get_unsafe< + fcppt::variant::get_unsafe< Type - >() + >( + _variant + ) ) } : diff --git a/libs/core/include/fcppt/variant/to_optional_ref.hpp b/libs/core/include/fcppt/variant/to_optional_ref.hpp index e433ff373..8dbdef0ef 100644 --- a/libs/core/include/fcppt/variant/to_optional_ref.hpp +++ b/libs/core/include/fcppt/variant/to_optional_ref.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -58,9 +59,11 @@ to_optional_ref( ? result_type{ fcppt::make_ref( - _variant. template get_unsafe< + fcppt::variant::get_unsafe< element_type - >() + >( + _variant + ) ) } : diff --git a/libs/core/include/fcppt/variant/type_info.hpp b/libs/core/include/fcppt/variant/type_info.hpp index 2964a8d36..239242cea 100644 --- a/libs/core/include/fcppt/variant/type_info.hpp +++ b/libs/core/include/fcppt/variant/type_info.hpp @@ -7,9 +7,10 @@ #ifndef FCPPT_VARIANT_TYPE_INFO_HPP_INCLUDED #define FCPPT_VARIANT_TYPE_INFO_HPP_INCLUDED +#include +#include #include #include -#include #include #include #include @@ -37,7 +38,24 @@ type_info( { return fcppt::variant::apply( - fcppt::variant::detail::type_info(), + []( + auto const &_value + ) + -> std::type_info const & + { + FCPPT_USE( + _value + ); + + return + typeid( + fcppt::type_traits::remove_cv_ref_t< + decltype( + _value + ) + > + ); + }, _variant ); } diff --git a/test/variant/CMakeLists.txt b/test/variant/CMakeLists.txt index 101ff72b7..e7b39392c 100644 --- a/test/variant/CMakeLists.txt +++ b/test/variant/CMakeLists.txt @@ -36,6 +36,10 @@ add_fcppt_variant_test( compare ) +add_fcppt_variant_test( + comparison +) + add_fcppt_variant_test( dynamic_cast LINK_LIBS @@ -47,16 +51,6 @@ add_fcppt_variant_test( NO_CODE ) -add_fcppt_variant_test( - equal -) - -add_fcppt_variant_test( - exception - LINK_LIBS - ${fcppt_core_TARGET} -) - add_fcppt_variant_test( get_exn LINK_LIBS @@ -69,10 +63,6 @@ add_fcppt_variant_test( Brigand ) -add_fcppt_variant_test( - less -) - add_fcppt_variant_test( match ) diff --git a/test/variant/assign.cpp b/test/variant/assign.cpp index da644eab3..74e497511 100644 --- a/test/variant/assign.cpp +++ b/test/variant/assign.cpp @@ -57,7 +57,8 @@ TEST_CASE( ) ); - test1 = 42; + test1 = + variant{42}; CHECK( fcppt::variant::holds_type< diff --git a/test/variant/equal.cpp b/test/variant/comparison.cpp similarity index 70% rename from test/variant/equal.cpp rename to test/variant/comparison.cpp index cfe5ded91..e87de8b2d 100644 --- a/test/variant/equal.cpp +++ b/test/variant/comparison.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -59,3 +60,46 @@ TEST_CASE( ) ); } + +TEST_CASE( + "variant less", + "[variant]" +) +{ + typedef + fcppt::variant::variadic< + int, + std::string + > + variant; + + variant const v1( + 10 + ); + + variant const v2( + 20 + ); + + CHECK( + v1 < v2 + ); + + CHECK_FALSE( + v2 < v1 + ); + + variant const v3( + std::string( + "hello world" + ) + ); + + CHECK( + v1 < v3 + ); + + CHECK_FALSE( + v3 < v1 + ); +} diff --git a/test/variant/exception.cpp b/test/variant/exception.cpp deleted file mode 100644 index ef7ebfa70..000000000 --- a/test/variant/exception.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#include -#include -#include -#include -#include -#include -#include - - -namespace -{ - -struct throw_cctor -{ - throw_cctor() - { - } - - [[ noreturn ]] - throw_cctor( - throw_cctor const & - ) - { - throw - fcppt::exception( - FCPPT_TEXT("Throwing cctor") - ); - } - - [[ noreturn ]] - throw_cctor( - throw_cctor && - ) - { - throw - fcppt::exception( - FCPPT_TEXT("Throwing move cctor") - ); - } - - throw_cctor & - operator=( - throw_cctor const & - ) = default; - - throw_cctor & - operator=( - throw_cctor && - ) = default; -}; - -} - -TEST_CASE( - "variant exception", - "[variant]" -) -{ - typedef - fcppt::variant::variadic< - std::string, - throw_cctor - > - variant; - - variant test( - std::string("test") - ); - - CHECK_FALSE( - test.is_invalid() - ); - - throw_cctor const test_cctor{}; - - CHECK_THROWS_AS( - test = - test_cctor, - fcppt::exception - ); - - CHECK( - test.is_invalid() - ); - - CHECK_THROWS_AS( - test = - throw_cctor(), - fcppt::exception - ); - - CHECK( - test.is_invalid() - ); -} diff --git a/test/variant/less.cpp b/test/variant/less.cpp deleted file mode 100644 index dcc203202..000000000 --- a/test/variant/less.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright Carl Philipp Reh 2009 - 2018. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - - -#include -#include -#include -#include -#include - - -TEST_CASE( - "variant less", - "[variant]" -) -{ - typedef - fcppt::variant::variadic< - int, - std::string - > - variant; - - variant const v1( - 10 - ); - - variant const v2( - 20 - ); - - CHECK( - v1 < v2 - ); - - CHECK_FALSE( - v2 < v1 - ); - - variant const v3( - std::string( - "hello world" - ) - ); - - CHECK( - v1 < v3 - ); - - CHECK_FALSE( - v3 < v1 - ); -}