![]() |
|
|||
File indexing completed on 2025-09-17 08:54:04
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file corecel/cont/VariantUtils.hh 0006 //! \brief Host-only utilities for use with std::variant 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <type_traits> 0011 #include <utility> 0012 0013 #include "corecel/Assert.hh" 0014 0015 #include "detail/VariantUtilsImpl.hh" 0016 0017 namespace celeritas 0018 { 0019 //---------------------------------------------------------------------------// 0020 /*! 0021 * Helper class for dispatching type-specific lambdas. 0022 * 0023 * Example applied to a variant that converts to int or string: \code 0024 std::visit(Overload{[](int a) { cout << a + 2; }, 0025 [](std::string const& s) { cout << '"' << s << '"'; }}, 0026 my_variant); 0027 * \endcode 0028 */ 0029 template<typename... Ts> 0030 struct Overload : Ts... 0031 { 0032 using Ts::operator()...; 0033 }; 0034 0035 // Template deduction guides 0036 template<class... Ts> 0037 Overload(Ts&&...) -> Overload<Ts...>; 0038 0039 template<class... Ts> 0040 Overload(Ts&...) -> Overload<Ts...>; 0041 0042 //---------------------------------------------------------------------------// 0043 /*! 0044 * Create a wrapper functor for unifying the return type. 0045 * 0046 * This provides a unified return type \c T (usually a variant) that can be 0047 * implicitly constructed from all return types of a functor \c F that operates 0048 * on a generic type \c U . The class is necessary because \c std::visit 0049 * requires all return types to be the same. 0050 * 0051 * Example: \code 0052 std::visit(return_as<VariantTransform>(Translate{{1,2,3}}), value); 0053 \endcode 0054 */ 0055 template<class T, class F> 0056 detail::ReturnAsImpl<T, F> return_as(F&& func) 0057 { 0058 return {std::forward<F>(func)}; 0059 } 0060 0061 //---------------------------------------------------------------------------// 0062 /*! 0063 * Define a variant that contains all the classes mapped by an enum+traits. 0064 * 0065 * For example: \code 0066 using VariantSurface = EnumVariant<SurfaceType, SurfaceTypeTraits>; 0067 * \endcode 0068 * is equivalent to: \code 0069 using VariantSurface = std::variant<PlaneX, PlaneY, ..., GeneralQuadric>; 0070 * \endcode 0071 * 0072 * \sa EnumClassUtils.hh 0073 */ 0074 template<class E, template<E> class ETraits> 0075 using EnumVariant = typename detail::EnumVariantImpl<E, ETraits>::type; 0076 0077 //---------------------------------------------------------------------------// 0078 /*! 0079 * Visit a container's element by calling "visit" on the corresponding index. 0080 * 0081 * example: \code 0082 std::vector<std::variant<int, std:string>> myvec{"hi", 123, "bye"}; 0083 ContainerVisitor visit_element{myvec}; 0084 visit_element([](auto&& v) { cout << v; }, 1); // Prints '123' 0085 visit_element([](auto&& v) { cout << v; }, 2); // Prints 'bye' 0086 \endcode 0087 */ 0088 template<class T, class U = typename std::remove_reference_t<T>::size_type> 0089 class ContainerVisitor 0090 { 0091 public: 0092 //!@{ 0093 //! \name Type aliases 0094 using index_type = U; 0095 //!@} 0096 0097 public: 0098 //! Construct with a container 0099 explicit ContainerVisitor(T&& container) 0100 : container_{std::forward<T>(container)} 0101 { 0102 } 0103 0104 //! Visit the functor upon the value at the given index 0105 template<class F> 0106 decltype(auto) operator()(F&& func, U const& idx) const 0107 { 0108 auto&& value = container_[idx]; 0109 CELER_ASSUME(!value.valueless_by_exception()); 0110 return std::visit(std::forward<F>(func), std::move(value)); 0111 } 0112 0113 private: 0114 T container_; 0115 }; 0116 0117 //---------------------------------------------------------------------------// 0118 // TEMPLATE DEDUCTION 0119 //---------------------------------------------------------------------------// 0120 template<class T> 0121 ContainerVisitor(T&&) -> ContainerVisitor<T>; 0122 0123 //---------------------------------------------------------------------------// 0124 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |