/** 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_FORMAT_ARGS_HPP #define REXY_DETAIL_FORMAT_FORMAT_ARGS_HPP #include //size_t #include //monostate #include "storage.hpp" //storage_type #include "basic_types.hpp" //arg_info #include "arg_store.hpp" #include "traits.hpp" #include "../../string_view.hpp" namespace rexy::fmt{ //Type erasure of single argument. //Context is an instantiation of 'basic_format_context' template class basic_format_arg { public: using char_type = typename Context::char_type; public: //Handles call to formatter for a user defined type //type erase the user defined values class handle { public: using format_ptr_t = void(handle::*)(basic_format_parse_context&, Context&)const; public: const void* m_data; format_ptr_t m_format_impl; public: template explicit handle(T&& t); template void format_impl(basic_format_parse_context& parse_ctx, Context& format_ctx)const; void format(basic_format_parse_context& parse_ctx, Context& format_ctx)const; }; union{ std::monostate none_v = {}; bool bool_v; char_type char_v; int int_v; unsigned int uint_v; long long long_long_v; unsigned long long ulong_long_v; float float_v; double double_v; long double long_double_v; const char_type* char_ptr_v; basic_string_view string_v; const void* ptr_v; handle custom_v; }; detail::storage_type active_member = detail::storage_type::none_t; //initialize std::variant equivalent to std::monostate basic_format_arg(void)noexcept{} explicit basic_format_arg(bool b)noexcept; explicit basic_format_arg(char_type b)noexcept; explicit basic_format_arg(int b)noexcept; explicit basic_format_arg(unsigned int b)noexcept; explicit basic_format_arg(long long b)noexcept; explicit basic_format_arg(unsigned long long b)noexcept; explicit basic_format_arg(float b)noexcept; explicit basic_format_arg(double b)noexcept; explicit basic_format_arg(long double b)noexcept; explicit basic_format_arg(const char_type* b)noexcept; explicit basic_format_arg(basic_string_view b)noexcept; explicit basic_format_arg(const void* b)noexcept; explicit basic_format_arg(const handle b)noexcept; detail::storage_type type(void)const; explicit operator bool(void)const noexcept; }; //Holds list of arguments, erasing concrete types. //Context is an instantiation of 'basic_format_context' template class basic_format_args { public: using char_type = detail::extract_char_type_from_context_t; private: //TODO less pointers const detail::arg_info* m_info = nullptr; const unsigned char* m_data = nullptr; const std::size_t m_num_args = 0; public: basic_format_args(void)noexcept = default; constexpr basic_format_args(const detail::basic_format_arg_store& store)noexcept; template basic_format_args(const detail::basic_format_arg_store& store)noexcept; basic_format_arg get(std::size_t i)const noexcept; basic_format_arg get(const char_type* first, const char_type* last)const; std::size_t get_index(const char_type* first, const char_type* last)const; }; //Visitor for basic_format_arg template decltype(auto) visit_format_arg(Fun&& fun, const basic_format_arg& arg); } #endif