2022-06-29 17:46:57 -07:00

112 lines
3.9 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_STORAGE_TPP
#define REXY_DETAIL_FORMAT_STORAGE_TPP
#include "storage.hpp"
#include "named_args.hpp"
#include <type_traits> //is_pointer, remove_cvref, remove_pointer, is_same, is_arithmetic
#include <concepts> //unsigned_integral, signed_integral, floating_point
#include <cstddef> //nullptr_t
namespace rexy::fmt::detail{
///////////////////////storage type mapping////////////////////////
template<class T, class Char>
consteval storage_type map_to_storage_enum(void){
using type = std::remove_cvref_t<T>;
if constexpr(std::is_pointer_v<type>){
if constexpr(std::is_same_v<std::remove_cv_t<std::remove_pointer_t<type>>,Char>){
return storage_type::char_ptr_t;
}else{
return storage_type::ptr_t;
}
}else if constexpr(std::is_same_v<type,basic_string_view<Char>>){
return storage_type::string_t;
}else if constexpr(std::is_same_v<type,Char>){
return storage_type::char_t;
}else if constexpr(std::is_same_v<type,std::monostate>){
return storage_type::none_t;
}else if constexpr(std::is_same_v<type,bool>){
return storage_type::bool_t;
}else if constexpr(std::is_same_v<type,int>){
return storage_type::int_t;
}else if constexpr(std::is_same_v<type,unsigned int>){
return storage_type::uint_t;
}else if constexpr(std::is_same_v<type,long long>){
return storage_type::long_long_t;
}else if constexpr(std::is_same_v<type,unsigned long long>){
return storage_type::ulong_long_t;
}else if constexpr(std::is_same_v<type,float>){
return storage_type::float_t;
}else if constexpr(std::is_same_v<type,double>){
return storage_type::double_t;
}else if constexpr(std::is_same_v<type,long double>){
return storage_type::long_double_t;
}else{
return storage_type::custom_t;
}
}
template<class Context>
struct map_to_stored_type_helper{
using char_type = typename Context::char_type;
template<class T>
requires (!std::is_arithmetic_v<T> && !std::is_pointer_v<T> && !NamedArg<T>)
constexpr auto operator()(T) -> typename basic_format_arg<Context>::handle;
constexpr auto operator()(std::unsigned_integral auto i){
if constexpr(sizeof(i) <= sizeof(unsigned int)){
return (unsigned int)(0);
}else{
return (unsigned long long)(0);
}
}
constexpr auto operator()(std::signed_integral auto i){
if constexpr(sizeof(i) <= sizeof(int)){
return int(0);
}else{
return (long long)(0);
}
}
template<std::floating_point T>
constexpr auto operator()(T) -> std::remove_cvref_t<T>;
constexpr auto operator()(char_type) -> char_type;
constexpr auto operator()(bool) -> bool;
constexpr auto operator()(float) -> float;
constexpr auto operator()(double) -> double;
constexpr auto operator()(long double) -> long double;
constexpr auto operator()(const char_type*) -> const char_type*;
constexpr auto operator()(basic_string_view<char_type>) -> basic_string_view<char_type>;
constexpr auto operator()(basic_string<char_type>) -> basic_string_view<char_type>;
template<class T>
requires (!std::is_same_v<std::remove_cvref_t<T>,char_type>)
constexpr auto operator()(T*) -> const void*;
constexpr auto operator()(std::nullptr_t) -> const void*;
template<NamedArg T>
constexpr auto operator()(T t) -> decltype((*this)(t.value));
};
}
#endif