131 lines
4.1 KiB
C++
131 lines
4.1 KiB
C++
/**
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef REXY_DETAIL_FORMAT_FORMAT_ARGS_HPP
|
|
#define REXY_DETAIL_FORMAT_FORMAT_ARGS_HPP
|
|
|
|
#include <cstddef> //size_t
|
|
#include <variant> //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 Context>
|
|
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<char_type>&, Context&)const;
|
|
public:
|
|
const void* m_data;
|
|
format_ptr_t m_format_impl;
|
|
public:
|
|
template<class T>
|
|
explicit handle(T&& t);
|
|
template<class T>
|
|
void format_impl(basic_format_parse_context<char_type>& parse_ctx, Context& format_ctx)const;
|
|
void format(basic_format_parse_context<char_type>& 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<char_type> 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<char_type> 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 Context>
|
|
class basic_format_args
|
|
{
|
|
public:
|
|
using char_type = detail::extract_char_type_from_context_t<Context>;
|
|
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<Context>& store)noexcept;
|
|
template<class... Args>
|
|
basic_format_args(const detail::basic_format_arg_store<Context,Args...>& store)noexcept;
|
|
|
|
basic_format_arg<Context> get(std::size_t i)const noexcept;
|
|
basic_format_arg<Context> 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<class Fun, class Context>
|
|
decltype(auto) visit_format_arg(Fun&& fun, const basic_format_arg<Context>& arg);
|
|
}
|
|
|
|
#endif
|