dlib C++ Library - overloaded.h

// Copyright (C) 2022 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_OVERLOADED_H_
#define DLIB_OVERLOADED_H_
#include <utility>
#include <type_traits>
namespace dlib
{
 namespace detail
 {
#if __cpp_fold_expressions
 template<typename ...Base>
 struct overloaded_helper : Base...
 {
 template<typename... T>
 constexpr overloaded_helper(T&& ... t)
 noexcept((std::is_nothrow_constructible<Base,T&&>::value && ...))
 : Base{std::forward<T>(t)}... {}
 using Base::operator()...;
 };
#else
 template<typename Base, typename ... BaseRest>
 struct overloaded_helper: Base, overloaded_helper<BaseRest...>
 {
 template<typename T, typename ... TRest>
 constexpr overloaded_helper(T&& t, TRest&& ...trest) 
 noexcept(std::is_nothrow_constructible<Base, T&&>::value && std::is_nothrow_constructible<overloaded_helper<BaseRest...>, TRest&&...>::value)
 : Base{std::forward<T>(t)},
 overloaded_helper<BaseRest...>{std::forward<TRest>(trest)...}
 {}
 using Base::operator();
 using overloaded_helper<BaseRest...>::operator();
 };
 template<typename Base>
 struct overloaded_helper<Base> : Base
 {
 template<typename T>
 constexpr overloaded_helper<Base>(T&& t) 
 noexcept(std::is_nothrow_constructible<Base, T&&>::value)
 : Base{std::forward<T>(t)}
 {}
 using Base::operator();
 };
#endif //__cpp_fold_expressions
 }
 
 template<typename... T>
 constexpr auto overloaded(T&&... t)
 /*!
 This is a helper function for combining many callable objects (usually lambdas), into
 an overload-able set. This can be used in visitor patterns like
 - dlib::type_safe_union::apply_to_contents()
 - dlib::visit()
 - dlib::for_each_type()
 - dlib::switch_()
 A picture paints a thousand words:
 using tsu = type_safe_union<int,float,std::string>;
 tsu a = std::string("hello there");
 std::string result;
 a.apply_to_contents(overloaded(
 [&result](int) {
 result = std::string("int");
 },
 [&result](float) {
 result = std::string("float");
 },
 [&result](const std::string& item) {
 result = item;
 }
 ));
 assert(result == "hello there");
 result = "";
 result = visit(overloaded(
 [](int) {
 return std::string("int");
 },
 [](float) {
 return std::string("float");
 },
 [](const std::string& item) {
 return item;
 }
 ), a);
 assert(result == "hello there");
 std::vector<int> type_ids;
 for_each_type(a, overloaded(
 [&type_ids](in_place_tag<int>, tsu& me) {
 type_ids.push_back(me.get_type_id<int>());
 },
 [&type_ids](in_place_tag<float>, tsu& me) {
 type_ids.push_back(me.get_type_id<float>());
 },
 [&type_ids](in_place_tag<std::string>, tsu& me) {
 type_ids.push_back(me.get_type_id<std::string>());
 }
 ));
 assert(type_ids == vector<int>({0,1,2}));
 !*/
 noexcept(std::is_nothrow_constructible<detail::overloaded_helper<std::decay_t<T>...>, T&&...>::value)
 {
 return detail::overloaded_helper<std::decay_t<T>...>{std::forward<T>(t)...};
 }
}
#endif //DLIB_OVERLOADED_H_

AltStyle によって変換されたページ (->オリジナル) /