Some minor cleanup to macros and future standard stuff
This commit is contained in:
parent
37e02ca871
commit
2a69be29a6
@ -10,6 +10,10 @@ set(librexy_VERSION_REVISION 0)
|
|||||||
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include)
|
set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include)
|
||||||
include_directories(BEFORE SYSTEM "${INCLUDE_PATH}")
|
include_directories(BEFORE SYSTEM "${INCLUDE_PATH}")
|
||||||
|
|
||||||
|
#find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
|
||||||
|
#if(CMAKE_CXX_CPPCHECK)
|
||||||
|
# list(APPEND CMAKE_CXX_CPPCHECK "--enable=warning" "--inconclusive" "--force" "--inline-suppr")
|
||||||
|
#endif()
|
||||||
|
|
||||||
cmake_dependent_option(ENABLE_SHARED "Build shared library" ON "NOT BUILD_HEADER_ONLY" OFF)
|
cmake_dependent_option(ENABLE_SHARED "Build shared library" ON "NOT BUILD_HEADER_ONLY" OFF)
|
||||||
cmake_dependent_option(ENABLE_SSO "Use small string optimization" ON "NOT BUILD_HEADER_ONLY" ON)
|
cmake_dependent_option(ENABLE_SSO "Use small string optimization" ON "NOT BUILD_HEADER_ONLY" ON)
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
#define REXY_DEFAULT_ALLOCATOR_HPP
|
#define REXY_DEFAULT_ALLOCATOR_HPP
|
||||||
|
|
||||||
#include <cstddef> //ptrdiff_t, size_t
|
#include <cstddef> //ptrdiff_t, size_t
|
||||||
#include <type_traits> //true_type, false_type, is_constant_evaluated
|
#include <type_traits> //true_type, false_type
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <limits> //numeric_limits
|
#include <limits> //numeric_limits
|
||||||
|
|
||||||
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "rexy.hpp"
|
#include "rexy.hpp"
|
||||||
#include "compat/standard.hpp"
|
#include "compat/standard.hpp"
|
||||||
|
#include "compat/if_consteval.hpp"
|
||||||
|
|
||||||
#include <type_traits> //declval
|
#include <type_traits> //declval
|
||||||
|
|
||||||
@ -82,11 +83,7 @@ namespace rexy{
|
|||||||
REXY_CPP20_CONSTEXPR pointer allocate(size_type n){
|
REXY_CPP20_CONSTEXPR pointer allocate(size_type n){
|
||||||
size_type bytes = has_overflow(n) ? std::numeric_limits<size_type>::max() : n*sizeof(T);
|
size_type bytes = has_overflow(n) ? std::numeric_limits<size_type>::max() : n*sizeof(T);
|
||||||
|
|
||||||
#ifdef __cpp_if_consteval
|
REXY_if_consteval{
|
||||||
if consteval{ //} //makes my braces matcher in nano not upset ;)
|
|
||||||
#else
|
|
||||||
if(std::is_constant_evaluated()){
|
|
||||||
#endif //__cpp_if_consteval
|
|
||||||
std::allocator<value_type> a;
|
std::allocator<value_type> a;
|
||||||
const size_type num_items = n / sizeof(value_type);
|
const size_type num_items = n / sizeof(value_type);
|
||||||
return a.allocate(num_items);
|
return a.allocate(num_items);
|
||||||
@ -101,11 +98,7 @@ namespace rexy{
|
|||||||
|
|
||||||
|
|
||||||
REXY_CPP20_CONSTEXPR void deallocate(pointer p, size_type n){
|
REXY_CPP20_CONSTEXPR void deallocate(pointer p, size_type n){
|
||||||
#ifdef __cpp_if_consteval
|
REXY_if_consteval{
|
||||||
if consteval{ //} //makes my braces matcher in nano not upset ;)
|
|
||||||
#else
|
|
||||||
if(std::is_constant_evaluated()){
|
|
||||||
#endif
|
|
||||||
std::allocator<value_type> a;
|
std::allocator<value_type> a;
|
||||||
const size_type num_items = n / sizeof(value_type);
|
const size_type num_items = n / sizeof(value_type);
|
||||||
return a.deallocate(p, num_items);
|
return a.deallocate(p, num_items);
|
||||||
|
|||||||
30
include/rexy/compat/if_consteval.hpp
Normal file
30
include/rexy/compat/if_consteval.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/**
|
||||||
|
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_if_consteval
|
||||||
|
|
||||||
|
#if defined(__cpp_if_consteval)
|
||||||
|
#define REXY_if_consteval if consteval
|
||||||
|
#define REXY_if_consteval if not consteval
|
||||||
|
#elif defined(__cpp_lib_is_constant_evaluated)
|
||||||
|
#include <type_traits> //is_constant_evaluated
|
||||||
|
#define REXY_if_consteval if(std::is_constant_evaluated())
|
||||||
|
#define REXY_if_not_consteval if(!std::is_constant_evaluated())
|
||||||
|
#endif //__cpp_if_consteval
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -29,11 +29,14 @@
|
|||||||
|
|
||||||
#if __cplusplus >= 202300L
|
#if __cplusplus >= 202300L
|
||||||
#define REXY_STANDARD_CPP23
|
#define REXY_STANDARD_CPP23
|
||||||
#elif __cplusplus >= 202002L
|
#endif
|
||||||
|
#if __cplusplus >= 202002L
|
||||||
#define REXY_STANDARD_CPP20
|
#define REXY_STANDARD_CPP20
|
||||||
#elif __cplusplus >= 201703L
|
#endif
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
#define REXY_STANDARD_CPP17
|
#define REXY_STANDARD_CPP17
|
||||||
#else //__cplusplus
|
#endif
|
||||||
|
#if __cplusplus < 201703L
|
||||||
#error "Requires minimum C++17 standard"
|
#error "Requires minimum C++17 standard"
|
||||||
#endif //__cplusplus
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
|||||||
@ -29,9 +29,41 @@ namespace rexy{
|
|||||||
|
|
||||||
template<class Left, class Right>
|
template<class Left, class Right>
|
||||||
class string_cat_expr;
|
class string_cat_expr;
|
||||||
|
template<class Char, REXY_ALLOCATOR_CONCEPT Alloc>
|
||||||
|
class basic_string;
|
||||||
|
template<class Char>
|
||||||
|
class basic_string_view;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_basic_string{
|
||||||
|
template<class Char, class Alloc>
|
||||||
|
static std::true_type check(const basic_string<Char,Alloc>*);
|
||||||
|
static std::false_type check(...);
|
||||||
|
|
||||||
|
static constexpr bool value = decltype(check(std::declval<std::remove_cvref_t<T>*>()))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_basic_string_view{
|
||||||
|
template<class Char>
|
||||||
|
static std::true_type check(const basic_string_view<Char>*);
|
||||||
|
static std::false_type check(...);
|
||||||
|
|
||||||
|
static constexpr bool value = decltype(check(std::declval<std::remove_cvref_t<T>*>()))::value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct is_basic_string_expr{
|
||||||
|
template<class Left, class Right>
|
||||||
|
static std::true_type check(const string_cat_expr<Left,Right>*);
|
||||||
|
static std::false_type check(...);
|
||||||
|
|
||||||
|
static constexpr bool value = decltype(check(std::declval<std::remove_cvref_t<T>*>()))::value;
|
||||||
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
concept BasicString = requires(const T& a){
|
concept BasicString = requires(const T& a){
|
||||||
|
requires(is_basic_string<T>::value || is_basic_string_view<T>::value);
|
||||||
{std::as_const(a).length()} -> std::convertible_to<typename std::decay_t<T>::size_type>;
|
{std::as_const(a).length()} -> std::convertible_to<typename std::decay_t<T>::size_type>;
|
||||||
{std::as_const(a).c_str()} -> std::convertible_to<typename std::decay_t<T>::const_pointer>;
|
{std::as_const(a).c_str()} -> std::convertible_to<typename std::decay_t<T>::const_pointer>;
|
||||||
{std::as_const(a)[0]} -> std::convertible_to<typename std::decay_t<T>::const_reference>;
|
{std::as_const(a)[0]} -> std::convertible_to<typename std::decay_t<T>::const_reference>;
|
||||||
@ -39,7 +71,7 @@ namespace rexy{
|
|||||||
{std::as_const(a).end()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
{std::as_const(a).end()} -> std::convertible_to<typename std::decay_t<T>::const_iterator>;
|
||||||
};
|
};
|
||||||
template<class T>
|
template<class T>
|
||||||
concept StringExpr = rexy::is_template_type<T,string_cat_expr>::value;
|
concept StringExpr = is_basic_string_expr<T>::value;
|
||||||
template<class T>
|
template<class T>
|
||||||
concept String = BasicString<T> || StringExpr<T>;
|
concept String = BasicString<T> || StringExpr<T>;
|
||||||
|
|
||||||
|
|||||||
@ -19,12 +19,13 @@
|
|||||||
#ifndef REXY_DETAIL_FORMAT_PARSE_CONTEXT_TPP
|
#ifndef REXY_DETAIL_FORMAT_PARSE_CONTEXT_TPP
|
||||||
#define REXY_DETAIL_FORMAT_PARSE_CONTEXT_TPP
|
#define REXY_DETAIL_FORMAT_PARSE_CONTEXT_TPP
|
||||||
|
|
||||||
|
#include "../../compat/if_consteval.hpp"
|
||||||
|
|
||||||
#include "parse_context.hpp"
|
#include "parse_context.hpp"
|
||||||
|
|
||||||
#include "format_error.hpp"
|
#include "format_error.hpp"
|
||||||
|
|
||||||
#include <cstddef> //size_t
|
#include <cstddef> //size_t
|
||||||
#include <type_traits> //is_constant_evaluated
|
|
||||||
|
|
||||||
namespace rexy::fmt{
|
namespace rexy::fmt{
|
||||||
|
|
||||||
@ -53,9 +54,11 @@ namespace rexy::fmt{
|
|||||||
//error, already in manual mode
|
//error, already in manual mode
|
||||||
REXY_THROW_FORMAT_ERROR("Invalid indexing mode switch");
|
REXY_THROW_FORMAT_ERROR("Invalid indexing mode switch");
|
||||||
}
|
}
|
||||||
if(std::is_constant_evaluated() && arg_index >= arg_count){
|
REXY_if_consteval{
|
||||||
|
if(arg_index >= arg_count){
|
||||||
REXY_THROW_FORMAT_ERROR("Missing argument");
|
REXY_THROW_FORMAT_ERROR("Missing argument");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return arg_index++;
|
return arg_index++;
|
||||||
}
|
}
|
||||||
template<class Char>
|
template<class Char>
|
||||||
@ -64,9 +67,11 @@ namespace rexy::fmt{
|
|||||||
//error, already in automatic mode
|
//error, already in automatic mode
|
||||||
REXY_THROW_FORMAT_ERROR("Invalid indexing mode switch");
|
REXY_THROW_FORMAT_ERROR("Invalid indexing mode switch");
|
||||||
}
|
}
|
||||||
if(std::is_constant_evaluated() && id >= arg_count){
|
REXY_if_consteval{
|
||||||
|
if(id >= arg_count){
|
||||||
REXY_THROW_FORMAT_ERROR("Missing argument");
|
REXY_THROW_FORMAT_ERROR("Missing argument");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
arg_index = detail::invalid_arg_index;
|
arg_index = detail::invalid_arg_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@
|
|||||||
#ifndef REXY_DETAIL_FORMAT_SPECS_HANDLER_HPP
|
#ifndef REXY_DETAIL_FORMAT_SPECS_HANDLER_HPP
|
||||||
#define REXY_DETAIL_FORMAT_SPECS_HANDLER_HPP
|
#define REXY_DETAIL_FORMAT_SPECS_HANDLER_HPP
|
||||||
|
|
||||||
#include <type_traits> //is_constant_evaluated
|
#include "../../compat/if_consteval.hpp"
|
||||||
|
|
||||||
namespace rexy::fmt::detail{
|
namespace rexy::fmt::detail{
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ namespace rexy::fmt::detail{
|
|||||||
|
|
||||||
constexpr cx_format_specs_handler(ParseCtx& pc, dynamic_format_specs<char_type>& s):
|
constexpr cx_format_specs_handler(ParseCtx& pc, dynamic_format_specs<char_type>& s):
|
||||||
dynamic_format_specs_handler<ParseCtx>(pc, s){
|
dynamic_format_specs_handler<ParseCtx>(pc, s){
|
||||||
if(!std::is_constant_evaluated()){
|
REXY_if_not_consteval{
|
||||||
throw 0;
|
throw 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,13 @@
|
|||||||
#include "string.hpp"
|
#include "string.hpp"
|
||||||
#include "string_view.hpp"
|
#include "string_view.hpp"
|
||||||
|
|
||||||
|
#include "compat/standard.hpp"
|
||||||
|
|
||||||
|
#ifndef REXY_STANDARD_CPP20
|
||||||
|
//Maybe I'll make it work someday, but not for now
|
||||||
|
#error "Cannot use formatting library without C++20 support"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "detail/format/standard_types.hpp"
|
#include "detail/format/standard_types.hpp"
|
||||||
#include "detail/format/internal_types.hpp"
|
#include "detail/format/internal_types.hpp"
|
||||||
#include "detail/format/arg_store.hpp"
|
#include "detail/format/arg_store.hpp"
|
||||||
|
|||||||
@ -26,16 +26,25 @@
|
|||||||
namespace rexy{
|
namespace rexy{
|
||||||
|
|
||||||
//new allocated string
|
//new allocated string
|
||||||
using string = basic_string<char,allocator<char>>;
|
using string = basic_string<char>;
|
||||||
using wstring = basic_string<wchar_t,allocator<wchar_t>>;
|
using wstring = basic_string<wchar_t>;
|
||||||
|
using u16string = basic_string<char16_t>;
|
||||||
|
using u32string = basic_string<char32_t>;
|
||||||
|
#ifdef __cpp_char8_t
|
||||||
|
using u8string = basic_string<char8_t>;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef LIBREXY_HEADER_ONLY
|
#ifndef LIBREXY_HEADER_ONLY
|
||||||
extern template class basic_string<char,allocator<char>>;
|
extern template class basic_string<char,allocator<char>>;
|
||||||
extern template class basic_string<wchar_t,allocator<wchar_t>>;
|
extern template class basic_string<wchar_t,allocator<wchar_t>>;
|
||||||
extern template class basic_string<char16_t,allocator<char16_t>>;
|
extern template class basic_string<char16_t,allocator<char16_t>>;
|
||||||
extern template class basic_string<char32_t,allocator<char32_t>>;
|
extern template class basic_string<char32_t,allocator<char32_t>>;
|
||||||
|
#ifdef __cpp_char8_t
|
||||||
|
extern template class basic_string<char8_t,allocator<char8_t>>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif //LIBREXY_HEADER_ONLY
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef REXY_CX_HASH_HPP
|
#ifdef REXY_CX_HASH_HPP
|
||||||
|
|||||||
@ -162,7 +162,6 @@ namespace rexy{
|
|||||||
}else if(len){
|
}else if(len){
|
||||||
set_islong_flag(false);
|
set_islong_flag(false);
|
||||||
pointer raw = set_short_ptr();
|
pointer raw = set_short_ptr();
|
||||||
if(len)
|
|
||||||
memcpy(raw, data, sizeof(value_type)*len);
|
memcpy(raw, data, sizeof(value_type)*len);
|
||||||
raw[len] = 0;
|
raw[len] = 0;
|
||||||
set_short_length(len);
|
set_short_length(len);
|
||||||
|
|||||||
@ -30,7 +30,7 @@ namespace rexy{
|
|||||||
static std::true_type check(U*);
|
static std::true_type check(U*);
|
||||||
static std::false_type check(...);
|
static std::false_type check(...);
|
||||||
|
|
||||||
static constexpr bool value = std::is_same<std::true_type,decltype(check(std::declval<std::decay_t<T>*>()))>::value;
|
static constexpr bool value = decltype(check(std::declval<std::decay_t<T>*>()))::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T, template<class...> class U>
|
template<class T, template<class...> class U>
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include <cwchar> //wcslen
|
#include <cwchar> //wcslen
|
||||||
#include <string> //char_traits
|
#include <string> //char_traits
|
||||||
|
|
||||||
|
#include "compat/if_consteval.hpp"
|
||||||
#include "rexy.hpp"
|
#include "rexy.hpp"
|
||||||
|
|
||||||
namespace rexy{
|
namespace rexy{
|
||||||
@ -91,14 +92,14 @@ namespace rexy{
|
|||||||
return val > 0 ? val : -val;
|
return val > 0 ? val : -val;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cpp_lib_is_constant_evaluated
|
#ifdef REXY_if_constexpr
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr size_t strlen(const T* c)noexcept{
|
constexpr size_t strlen(const T* c)noexcept{
|
||||||
return std::char_traits<T>::length(c);
|
return std::char_traits<T>::length(c);
|
||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr int strcmp(const T* l, const T* r)noexcept{
|
constexpr int strcmp(const T* l, const T* r)noexcept{
|
||||||
if(!std::is_constant_evaluated()){
|
REXY_if_constexpr{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strcmp(l, r);
|
return std::strcmp(l, r);
|
||||||
}else if constexpr(std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr(std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -110,7 +111,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr int strncmp(const T* l, const T* r, std::size_t max)noexcept{
|
constexpr int strncmp(const T* l, const T* r, std::size_t max)noexcept{
|
||||||
if(!std::is_constant_evaluated()){
|
REXY_if_constexpr{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strncmp(l, r, max);
|
return std::strncmp(l, r, max);
|
||||||
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -122,7 +123,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
template<class T, class Compare>
|
template<class T, class Compare>
|
||||||
constexpr int strncmp(const T* l, const T* r, std::size_t max, Compare cmp)noexcept{
|
constexpr int strncmp(const T* l, const T* r, std::size_t max, Compare cmp)noexcept{
|
||||||
if(!std::is_constant_evaluated()){
|
REXY_if_constexpr{
|
||||||
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
if constexpr(std::is_same_v<std::remove_cvref_t<T>,char>){
|
||||||
return std::strncmp(l, r, max);
|
return std::strncmp(l, r, max);
|
||||||
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
}else if constexpr (std::is_same_v<std::remove_cvref_t<T>,wchar_t>){
|
||||||
@ -138,7 +139,7 @@ namespace rexy{
|
|||||||
return *l - *r;
|
return *l - *r;
|
||||||
}
|
}
|
||||||
constexpr void memcpy(void* l, const void* r, size_t n){
|
constexpr void memcpy(void* l, const void* r, size_t n){
|
||||||
if(!std::is_constant_evaluated()){
|
REXY_if_constexpr{
|
||||||
std::memcpy(l, r, n);
|
std::memcpy(l, r, n);
|
||||||
}else{
|
}else{
|
||||||
char* ld = static_cast<char*>(l);
|
char* ld = static_cast<char*>(l);
|
||||||
@ -149,7 +150,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else //__cpp_lib_is_constant_evaluated
|
#else // REXY_if_constexpr
|
||||||
template<class T>
|
template<class T>
|
||||||
constexpr size_t strlen(const T* c)noexcept{
|
constexpr size_t strlen(const T* c)noexcept{
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
@ -179,7 +180,7 @@ namespace rexy{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif //__cpp_lib_is_constant_evaluated
|
#endif // REXY_if_constexpr
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,5 +25,8 @@ namespace rexy{
|
|||||||
template class basic_string<wchar_t,allocator<wchar_t>>;
|
template class basic_string<wchar_t,allocator<wchar_t>>;
|
||||||
template class basic_string<char16_t,allocator<char16_t>>;
|
template class basic_string<char16_t,allocator<char16_t>>;
|
||||||
template class basic_string<char32_t,allocator<char32_t>>;
|
template class basic_string<char32_t,allocator<char32_t>>;
|
||||||
|
#ifdef __cpp_char8_t
|
||||||
|
template class basic_string<char8_t,allocator<char8_t>>;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user