//===----------------------------------------------------------------------===// // // Part of CUDA Experimental in CUDA C++ Core Libraries, // under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. // //===----------------------------------------------------------------------===// #pragma once #include #include #include #include #include #include #include #include template class result_wrapper_t { std::shared_ptr m_owner; public: result_wrapper_t() : m_owner{} {} result_wrapper_t(ResultT v) : m_owner{std::make_shared(v)} {} result_wrapper_t(const result_wrapper_t&) = default; result_wrapper_t(result_wrapper_t&&) = default; result_wrapper_t& operator=(const result_wrapper_t&) = default; result_wrapper_t& operator=(result_wrapper_t&&) = default; ~result_wrapper_t() noexcept try { if (!m_owner) { return; } if (m_owner.use_count() <= 1) { // release resources CleanupCallable{}(m_owner.get()); } } catch (const std::exception& e) { std::cerr << "~result_wrapper_t ignores exception: " << e.what() << '\n'; } ResultT& get() { return *m_owner.get(); } }; template class build_cache_t { std::unordered_map m_map{}; public: build_cache_t() = default; bool contains(const KeyT& key) const { // unorder_map::contains is C++20 feature return m_map.contains(key); } void insert(const KeyT& key, ValueT&& new_value) { m_map[key] = std::move(new_value); } ValueT& get(const KeyT& key) { assert(m_map.contains(key)); return m_map[key]; } }; template class fixture { public: using OptionalT = typename std::optional; private: OptionalT v; fixture() : v{T{}} {} public: OptionalT& get_value() { return v; } static auto& get_or_create() { static fixture singleton{}; return singleton; } }; struct KeyBuilder { static std::string bool_as_key(bool v) { return (v) ? std::string("T") : std::string("F"); } template static std::string type_as_key() { return typeid(T).name(); } template static std::string join(const std::string (&collection)[N]) { constexpr std::string_view delimiter = "-"; std::stringstream ss; for (std::size_t i = 0; i < N; ++i) { ss << collection[i]; if (i + 1 < N) { ss << delimiter; } } return ss.str(); } }; template void adder_helper(std::stringstream& ss) { constexpr std::size_t S = std::tuple_size_v; if constexpr (I < S) { using SelectedType = std::tuple_element_t; constexpr std::size_t In = I + 1; ss << KeyBuilder::type_as_key(); if constexpr (In < S) { ss << "-"; } adder_helper(ss); } } template std::optional make_key() { std::stringstream ss{}; adder_helper, 0>(ss); return std::make_optional(ss.str()); }