/** 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_TRAITS_HPP #define REXY_DETAIL_FORMAT_TRAITS_HPP #include //is_convertible, is_floating_point, integral_constant, is_same, remove_cvref #include //integral, floating_point #include //size_t #include "standard_types.hpp" #include "storage.hpp" #include "named_args.hpp" #include "internal_types.hpp" namespace rexy::fmt::detail{ template struct valid_dynamic_index{ static constexpr bool value = std::is_convertible_v && !std::is_floating_point_v; }; template static constexpr bool valid_dynamic_index_v = valid_dynamic_index::value; template struct is_char_or_bool : public std::false_type{}; template<> struct is_char_or_bool : public std::true_type{}; template<> struct is_char_or_bool : public std::true_type{}; template<> struct is_char_or_bool : public std::true_type{}; template concept Integral = std::integral && !is_char_or_bool::value; template concept Bool = std::is_same_v,bool>; template concept Floating = std::floating_point; template concept Arithmetic = Integral || Floating; template concept Handle = std::is_same_v,typename basic_format_arg::handle>; template concept Formatter_Char = std::is_same_v || std::is_same_v; template struct is_handle{ static constexpr bool value = Handle; }; template static constexpr bool is_handle_v = is_handle::value; template struct extract_char_type_from_context; template struct extract_char_type_from_context>{ using type = Char; }; template using extract_char_type_from_context_t = typename extract_char_type_from_context::type; template constexpr bool is_dynamic_integer_impl(int index){ using mapped_t = stored_type_t; if(index == I){ return valid_dynamic_index_v; } if constexpr(sizeof...(Args) > 0){ return is_dynamic_integer_impl(index); } return false; } template constexpr bool is_dynamic_integer(int index){ using fmt_ctx_t = fmt_context_t; if constexpr(sizeof...(Args) == 0){ return false; }else{ return is_dynamic_integer_impl<0,fmt_ctx_t,Args...>(index); } } static constexpr unsigned char utf_test[] = "\u00B5"; constexpr bool is_utf8(void){ using uchar = unsigned char; return (sizeof(utf_test) == 3) && (uchar(utf_test[0]) == 0xC2) && (uchar(utf_test[1]) == 0xB5); } template struct is_utf8_encoded_string_type{ static constexpr bool value = false; }; template<> struct is_utf8_encoded_string_type{ static constexpr bool value = true; }; template<> struct is_utf8_encoded_string_type{ static constexpr bool value = is_utf8(); }; template static constexpr bool is_utf8_encoded_string_type_v = is_utf8_encoded_string_type::value; template concept UTF8_String = is_utf8_encoded_string_type_v; } #endif