diff --git a/cetlvast/suites/unittest/test_pf17_variant_other.cpp b/cetlvast/suites/unittest/test_pf17_variant_other.cpp index 3d49599..25a4730 100644 --- a/cetlvast/suites/unittest/test_pf17_variant_other.cpp +++ b/cetlvast/suites/unittest/test_pf17_variant_other.cpp @@ -8,6 +8,7 @@ // CSpell: words chronomorphize #include // The tested header always goes first. +#include #include "test_pf17_variant.hpp" #include @@ -675,7 +676,7 @@ TEST(test_variant, basic_operations) using cetl::pf17::holds_alternative; using cetl::pf17::get; using cetl::pf17::get_if; - using cetl::pf17::make_overloaded; + using cetl::make_overloaded; using cetl::pf17::in_place_index; variant var; @@ -818,7 +819,7 @@ TEST(test_variant, visit) using cetl::pf17::get; using cetl::pf17::visit; using cetl::pf17::monostate; - using cetl::pf17::make_overloaded; + using cetl::make_overloaded; #if __cpp_exceptions using cetl::pf17::bad_variant_access; #endif @@ -898,7 +899,7 @@ TEST(test_variant, visit) // Constexpr visitation is not possible in C++14. #if __cplusplus >= 201703L - using cetl::pf17::make_overloaded; + using cetl::make_overloaded; using cetl::pf17::in_place_type; static_assert(1110 == visit(make_overloaded([](const std::int8_t a, const float b) { return a + static_cast(b); }, diff --git a/include/cetl/pf17/utility.hpp b/include/cetl/pf17/utility.hpp index 3579c12..dc38402 100644 --- a/include/cetl/pf17/utility.hpp +++ b/include/cetl/pf17/utility.hpp @@ -55,54 +55,6 @@ constexpr in_place_index_t in_place_index{}; // -------------------------------------------------------------------------------------------- -/// This is a helper for use with \ref visit that uses standard overload resolution to pick the best overload -/// among a set of lambdas given by the user. Unfortunately, in C++14 we have to use it with a factory function; -/// please see \ref make_overloaded for details. In C++17 this can be used without the factory in a much simpler way. -/// -/// This function is not found in the C++ standard library, but is a common extension in the wild. -template -struct overloaded; -template -struct overloaded : public T -{ - using T::operator(); - // SFINAE is needed to ensure this constructor does not hide the copy/move constructors. - template , std::decay_t>::value, int> = 0> - constexpr explicit overloaded(A&& arg) - : T(std::forward(arg)) - { - } -}; -template -struct overloaded : public T, public overloaded -{ - using T::operator(); - using overloaded::operator(); - // If B were empty, the ctor would need sfinae to avoid hiding the copy/move ctors; ensure this is not so. - template 0), int> = 0> - constexpr explicit overloaded(A&& a, B&&... b) - : T(std::forward(a)) - , overloaded(std::forward(b)...) - { - } -}; - -/// Returns an instance of \ref overloaded that can be used with \ref visit. The usage is as follows: -/// @code -/// visit(make_overloaded( -/// [](const auto&) { return "fallback"; }, -/// [](double) { return "double"; }, -/// [](const std::string&) { return "string"; } -/// ), variant); -/// @endcode -template -constexpr overloaded make_overloaded(Ts&&... ts) -{ - return overloaded(std::forward(ts)...); -} - -// -------------------------------------------------------------------------------------------- - // Non-standard extensions for internal use. // We keep the definitions here to make it clear they are designed to detect the above-defined types, not std:: ones. namespace detail diff --git a/include/cetl/visit_helpers.hpp b/include/cetl/visit_helpers.hpp new file mode 100644 index 0000000..b522a10 --- /dev/null +++ b/include/cetl/visit_helpers.hpp @@ -0,0 +1,64 @@ +/// @file +/// Contains helpers for building visitors for the `cetl::visit` invocation. +/// +/// @copyright +/// Copyright (C) OpenCyphal Development Team +/// Copyright Amazon.com Inc. or its affiliates. +/// SPDX-License-Identifier: MIT + +#ifndef CETL_VISIT_HELPERS_HPP_INCLUDED +#define CETL_VISIT_HELPERS_HPP_INCLUDED + +#include + +namespace cetl +{ +/// This is a helper for use with \ref visit that uses standard overload resolution to pick the best overload +/// among a set of lambdas given by the user. Unfortunately, in C++14 we have to use it with a factory function; +/// please see \ref make_overloaded for details. In C++17 this can be used without the factory in a much simpler way. +/// +/// This function is not found in the C++ standard library, but is a common extension in the wild. +template +struct overloaded; +template +struct overloaded : public T +{ + using T::operator(); + // SFINAE is needed to ensure this constructor does not hide the copy/move constructors. + template , std::decay_t>::value, int> = 0> + constexpr explicit overloaded(A&& arg) + : T(std::forward(arg)) + { + } +}; +template +struct overloaded : public T, public overloaded +{ + using T::operator(); + using overloaded::operator(); + // If B were empty, the ctor would need sfinae to avoid hiding the copy/move ctors; ensure this is not so. + template 0), int> = 0> + constexpr explicit overloaded(A&& a, B&&... b) + : T(std::forward(a)) + , overloaded(std::forward(b)...) + { + } +}; + +/// Returns an instance of \ref overloaded that can be used with \ref visit. The usage is as follows: +/// @code +/// visit(make_overloaded( +/// [](const auto&) { return "fallback"; }, +/// [](double) { return "double"; }, +/// [](const std::string&) { return "string"; } +/// ), variant); +/// @endcode +template +constexpr overloaded make_overloaded(Ts&&... ts) +{ + return overloaded(std::forward(ts)...); +} + +} // namespace cetl + +#endif // CETL_VISIT_HELPERS_HPP_INCLUDED