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