106 lines
2.7 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_ARG_STORE_HPP
#define REXY_DETAIL_FORMAT_ARG_STORE_HPP
#include <cstddef> //size_t
#include "basic_types.hpp" //arg_info
#include "storage.hpp" //stored_type
#include "named_args.hpp" //count_named_args
#include "../../string_view.hpp"
namespace rexy::fmt::detail{
//Implementation of argument storage, erasing the need of passing around a parameter pack. Used in
//constructor of basic_format_args
template<class Context, class... Args>
class basic_format_arg_store
{
public:
using char_type = typename Context::char_type;
public:
static constexpr std::size_t num_args = sizeof...(Args);
static constexpr std::size_t num_named_args = count_named_args_v<Args...>;
struct format_data
{
friend class basic_format_arg_store;
private:
unsigned char m_data[
(sizeof(arg_info) * num_args) +
(sizeof(basic_string_view<char_type>) * num_named_args) +
(sizeof(stored_type_t<Args,Context>) + ...)
] = {};
arg_info* info(void){
return reinterpret_cast<arg_info*>(raw_info());
}
constexpr unsigned char* data(void){
return raw_info() + (sizeof(arg_info) * num_args);
}
constexpr unsigned char* raw_info(void){
return m_data;
}
constexpr const unsigned char* raw_info(void)const{
return m_data;
}
public:
const arg_info* info(void)const{
return reinterpret_cast<const arg_info*>(raw_info());
}
const unsigned char* data(void)const{
return raw_info() + (sizeof(arg_info) * num_args);
}
const unsigned char* raw(void)const{
return m_data;
}
}packed_data;
basic_format_arg_store(Args&&... args);
private:
template<class Arg>
void store_arg(std::size_t argnum, Arg&& arg);
template<NamedArg Arg>
void store_arg(std::size_t argnum, Arg&& arg);
template<class... SArgs>
void store_args(SArgs&&... args);
};
//Specialized for empty parameter pack
template<class Context>
class basic_format_arg_store<Context>
{
public:
static constexpr std::size_t num_args = 0;
};
}
#endif