// MIT License // // Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #pragma once #include "common.hpp" #include "defines.hpp" #include "get_categories.hpp" #include "info_type.hpp" #include #include #include #include #include #include #include #include //--------------------------------------------------------------------------------------// struct unknown {}; template constexpr bool available_value_type_alias(int) { return true; } template constexpr bool available_value_type_alias(long) { return false; } template struct component_value_type; template struct component_value_type { using type = typename Type::value_type; }; template struct component_value_type { using type = unknown; }; template using component_value_type_t = typename component_value_type(0)>::type; //--------------------------------------------------------------------------------------// template struct get_availability; //--------------------------------------------------------------------------------------// template struct get_availability { using this_type = get_availability; using metadata_t = ::tim::component::metadata; using property_t = ::tim::component::properties; static info_type get_info(); auto operator()() const { return get_info(); } }; //--------------------------------------------------------------------------------------// template struct get_availability> { using data_type = std::vector; static data_type get_info(data_type& _v) { TIMEMORY_FOLD_EXPRESSION(_v.emplace_back(get_availability::get_info())); return _v; } static data_type get_info() { data_type _v{}; return get_info(_v); } template decltype(auto) operator()(Args&&... _args) { return get_info(std::forward(_args)...); } }; //--------------------------------------------------------------------------------------// template info_type get_availability::get_info() { using namespace tim; using value_type = component_value_type_t; using category_types = typename trait::component_apis::type; auto _cleanup = [](std::string _type, const std::string& _pattern) { auto _pos = std::string::npos; while((_pos = _type.find(_pattern)) != std::string::npos) _type.erase(_pos, _pattern.length()); return _type; }; auto _replace = [](std::string _type, const std::string& _pattern, const std::string& _with) { auto _pos = std::string::npos; while((_pos = _type.find(_pattern)) != std::string::npos) _type.replace(_pos, _pattern.length(), _with); return _type; }; bool has_metadata = metadata_t::specialized(); bool has_properties = property_t::specialized(); bool is_available = trait::is_available::value; bool file_output = trait::generates_output::value; auto name = component::metadata::name(); auto label = (file_output) ? ((has_metadata) ? metadata_t::label() : Type::get_label()) : std::string(""); auto description = (has_metadata) ? metadata_t::description() : Type::get_description(); auto data_type = demangle(); string_t enum_type = property_t::enum_string(); string_t id_type = property_t::id(); auto ids_set = property_t::ids(); if(!has_properties) { enum_type = ""; id_type = ""; ids_set.clear(); } string_t ids_str = {}; { auto itr = ids_set.begin(); string_t db = (markdown) ? "`\"" : (csv) ? "" : "\""; string_t de = (markdown) ? "\"`" : (csv) ? "" : "\""; if(has_metadata) description += ". " + metadata_t::extra_description(); description += "."; while(itr->empty()) ++itr; if(itr != ids_set.end()) ids_str = TIMEMORY_JOIN("", TIMEMORY_JOIN("", db, *itr++, de)); for(; itr != ids_set.end(); ++itr) { if(!itr->empty()) ids_str = TIMEMORY_JOIN(", ", ids_str, TIMEMORY_JOIN("", db, *itr, de)); } } string_t categories = get_categories(category_types{}); description = _replace(_replace(description, ". .", "."), "..", "."); data_type = _replace(_cleanup(data_type, "::__1"), "> >", ">>"); return info_type{ name, is_available, str_vec_t{ data_type, enum_type, id_type, ids_str, label, description, categories } }; } //--------------------------------------------------------------------------------------// template <> struct get_availability { template decltype(auto) operator()(tim::type_list, Args&&... _args) const { return get_availability>{}(std::forward(_args)...); } template decltype(auto) operator()(Args&&... _args) const { return get_availability>{}(std::forward(_args)...); } };