/** This file is a part of rexy's general purpose library Copyright (C) 2022 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef REXY_DETAIL_FORMAT_NAMED_ARGS_HPP #define REXY_DETAIL_FORMAT_NAMED_ARGS_HPP #include //remove_cvref, declval, integral_constant #include //forward #include //size_t #include "../../string_view.hpp" namespace rexy::fmt{ namespace detail{ template struct arg_base{ const T& value; const basic_string_view name; }; //class used to store name and value for runtime analysis of named arguments //the type T is the actual formatted type and name is used only for lookup //during runtime formatting template struct runtime_arg : public arg_base{ using char_type = Char; using value_type = std::remove_cvref_t; }; //class used to store name and value for compile time analysis of named arguments //the type T is the actual formatted type and Name is used for name lookup in //format string checking template struct static_arg : public arg_base{ using char_type = typename decltype(Name)::value_type; using value_type = std::remove_cvref_t; static constexpr auto static_name = Name; constexpr static_arg(const T& v): arg_base{v, {Name.c_str(), Name.length()}}{} static_arg(const static_arg&) = delete; constexpr static_arg(static_arg&&) = default; }; //temporary object to store Name to pass off to a compile time argument during assignment template struct arg_literal_result{ template constexpr auto operator=(T&& t){ return static_arg, Name>{std::forward(t)}; } }; template struct is_runtime_named_arg{ template static auto check(runtime_arg) -> std::true_type; static auto check(...) -> std::false_type; static constexpr bool value = decltype(check(std::declval>()))::value; }; template static constexpr bool is_runtime_named_arg_v = is_runtime_named_arg::value; template struct is_static_named_arg{ template static auto check(static_arg) -> std::true_type; static auto check(...) -> std::false_type; static constexpr bool value = decltype(check(std::declval>()))::value; }; template static constexpr bool is_static_named_arg_v = is_static_named_arg::value; template concept RuntimeNamedArg = is_runtime_named_arg_v; template concept StaticNamedArg = is_static_named_arg_v; template concept NamedArg = StaticNamedArg || RuntimeNamedArg; template constexpr std::size_t find_static_named_arg_id_impl(It first, It last); template constexpr std::size_t find_static_named_arg_id(It first, It last); template struct count_named_args{ static constexpr std::size_t value = (std::size_t{NamedArg} + ...); }; template static constexpr std::size_t count_named_args_v = count_named_args::value; } } #endif