diff --git a/CMakeLists.txt b/CMakeLists.txt
index 64fa6f0..70c5a80 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,7 +17,7 @@ mark_as_advanced(ENABLE_PROFILING)
set(SOURCE_LIST "src/filerd.cpp" "src/string.cpp" "src/binary.cpp" "src/static_string.cpp" "src/threadpool.cpp")
add_library(ensure OBJECT "src/ensure.cpp")
-target_compile_options(ensure PRIVATE -Wall -Wextra -pedantic -std=c++17)
+target_compile_options(ensure PRIVATE -Wall -Wextra -pedantic -std=c++20)
if(ENABLE_SHARED)
add_library(rexy SHARED ${SOURCE_LIST})
set_target_properties(rexy PROPERTIES SOVERSION "${librexy_VERSION_MAJOR}.${librexy_VERSION_MINOR}")
@@ -39,8 +39,8 @@ if(BUILD_TESTS)
add_subdirectory(tests)
endif()
-set(LIBREXY_PUBLIC_HEADERS "include/rexy/rexy.hpp" "include/rexy/algorithm.hpp" "include/rexy/utility.hpp" "include/rexy/basic_string_hash.hpp" "include/rexy/hash.hpp" "include/rexy/static_string_hash.hpp" "include/rexy/string_hash.hpp" "include/rexy/mpmc_queue.hpp" "include/rexy/mpmc_queue.tpp" "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/allocator.hpp" "include/rexy/meta.hpp" "include/rexy/buffer.hpp" "include/rexy/buffer.tpp")
-target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++17)
+set(LIBREXY_PUBLIC_HEADERS "include/rexy/rexy.hpp" "include/rexy/algorithm.hpp" "include/rexy/utility.hpp" "include/rexy/basic_string_hash.hpp" "include/rexy/hash.hpp" "include/rexy/static_string_hash.hpp" "include/rexy/string_hash.hpp" "include/rexy/mpmc_queue.hpp" "include/rexy/mpmc_queue.tpp" "include/rexy/traits.hpp" "include/rexy/steal.hpp" "include/rexy/binary.hpp" "include/rexy/expression.hpp" "include/rexy/binary_base.hpp" "include/rexy/binary_base.tpp" "include/rexy/string_base.hpp" "include/rexy/string.hpp" "include/rexy/filerd.hpp" "include/rexy/string_base.tpp" "include/rexy/allocator.hpp" "include/rexy/meta.hpp" "include/rexy/buffer.hpp" "include/rexy/buffer.tpp" "include/rexy/debug_print.hpp" "include/rexy/deferred.hpp" "include/rexy/demangle.hpp" "include/rexy/enum_traits.hpp" "include/rexy/source_location.hpp")
+target_compile_options(rexy PRIVATE -Wall -Wextra -pedantic -std=c++20)
install(TARGETS rexy
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
diff --git a/include/rexy/debug_print.hpp b/include/rexy/debug_print.hpp
new file mode 100644
index 0000000..55f5c77
--- /dev/null
+++ b/include/rexy/debug_print.hpp
@@ -0,0 +1,155 @@
+/**
+ 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_DEBUG_PRINT_HPP
+#define REXY_DEBUG_PRINT_HPP
+
+#ifndef REXY_ENABLE_DEBUG_LEVEL
+ #define REXY_ENABLE_DEBUG_LEVEL 0
+#endif
+
+#ifndef REXY_ENABLE_COLOR_DEBUG
+ #define REXY_ENABLE_COLOR_DEBUG 1
+#endif
+
+//Debug output section
+#if REXY_ENABLE_DEBUG_LEVEL > 0
+ #define REXY_ENABLE_DEBUG_OUTPUT
+#endif
+#if REXY_ENABLE_DEBUG_LEVEL > 2
+ #define REXY_ENABLE_DEBUG_VERBOSE_OUTPUT
+#endif
+
+
+#ifdef REXY_ENABLE_DEBUG_OUTPUT
+ #include //fprintf, vfprintf
+ #include //forward
+
+ #include "source_location.hpp"
+
+
+ namespace rexy::debug{
+ namespace detail{
+ static constexpr const char color_red[] = "\033[38;5;9m";
+ static constexpr const char color_yellow[] = "\033[38;5;11m";
+ static constexpr const char color_green[] = "\033[38;5;2m";
+ static constexpr const char color_blue[] = "\033[38;5;12m";
+ static constexpr const char color_clear[] = "\033[0m";
+ }
+ template
+ struct print{
+ explicit print(Args&&... args, const rexy::source_location& loc = rexy::source_location::current()){
+ std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line());
+ std::fprintf(stderr, std::forward(args)...);
+ }
+ print(const print&) = delete;
+ print(print&&) = delete;
+ print& operator=(const print&) = delete;
+ print& operator=(print&&) = delete;
+ };
+ template
+ print(Args&&...) -> print;
+ #ifdef REXY_ENABLE_COLOR_DEBUG
+ template
+ struct print_info{
+ explicit print_info(Args&&... args, const rexy::source_location& loc = rexy::source_location::current()){
+ std::fprintf(stderr, "%s", detail::color_blue);
+ std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line());
+ std::fprintf(stderr, std::forward(args)...);
+ std::fprintf(stderr, "%s", detail::color_clear);
+ }
+ print_info(const print_info&) = delete;
+ print_info(print_info&&) = delete;
+ print_info& operator=(const print_info&) = delete;
+ print_info& operator=(print_info&&) = delete;
+ };
+ template
+ print_info(Args&&...) -> print_info;
+ template
+ struct print_warn{
+ explicit print_warn(Args&&... args, const rexy::source_location& loc = rexy::source_location::current()){
+ std::fprintf(stderr, "%s", detail::color_yellow);
+ std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line());
+ std::fprintf(stderr, std::forward(args)...);
+ std::fprintf(stderr, "%s", detail::color_clear);
+ }
+ print_warn(const print_warn&) = delete;
+ print_warn(print_warn&&) = delete;
+ print_warn& operator=(const print_warn&) = delete;
+ print_warn& operator=(print_warn&&) = delete;
+ };
+ template
+ print_warn(Args&&...) -> print_warn;
+ template
+ struct print_error{
+ explicit print_error(Args&&... args, const rexy::source_location& loc = rexy::source_location::current()){
+ std::fprintf(stderr, "%s", detail::color_red);
+ std::fprintf(stderr, "%s:%s:%d: ", loc.file_name(), loc.function_name(), loc.line());
+ std::fprintf(stderr, std::forward(args)...);
+ std::fprintf(stderr, "%s", detail::color_clear);
+ }
+ print_error(const print_error&) = delete;
+ print_error(print_error&&) = delete;
+ print_error& operator=(const print_error&) = delete;
+ print_error& operator=(print_error&&) = delete;
+ };
+ template
+ print_error(Args&&...) -> print_error;
+ #else
+ template
+ using print_info = print;
+ template
+ using print_warn = print;
+ template
+ using print_error = print;
+ #endif //REXY_ENABLE_COLOR_DEBUG
+
+ #ifdef REXY_ENABLE_DEBUG_VERBOSE_OUTPUT
+ namespace verbose{
+ template
+ using print = rexy::debug::print;
+ template
+ using print_info = rexy::debug::print_info;
+ template
+ using print_warn = rexy::debug::print_warn;
+ template
+ using print_error = rexy::debug::print_error;
+ }
+ #else
+ namespace verbose{
+ static constexpr inline void print(...){}
+ static constexpr inline void print_warn(...){}
+ static constexpr inline void print_error(...){}
+ static constexpr inline void print_info(...){}
+ }
+ #endif //REXY_ENABLE_DEBUG_VERBOSE_OUTPUT
+ }
+#else
+ static constexpr inline void print(...){}
+ static constexpr inline void print_warn(...){}
+ static constexpr inline void print_error(...){}
+ static constexpr inline void print_info(...){}
+ namespace verbose{
+ static constexpr inline void print(...){}
+ static constexpr inline void print_warn(...){}
+ static constexpr inline void print_error(...){}
+ static constexpr inline void print_info(...){}
+ }
+#endif //REXY_ENABLE_DEBUG_OUTPUT
+
+#endif
diff --git a/include/rexy/deferred.hpp b/include/rexy/deferred.hpp
new file mode 100644
index 0000000..d246b09
--- /dev/null
+++ b/include/rexy/deferred.hpp
@@ -0,0 +1,131 @@
+/**
+ 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_UTIL_DEFERRED_HPP
+#define REXY_UTIL_DEFERRED_HPP
+
+#include
+#include //forward, index_sequence
+
+namespace rexy{
+ template
+ class deferred
+ {
+ public:
+ using value_type = T;
+
+ private:
+ std::tuple m_args;
+
+ public:
+ template
+ constexpr deferred(FArgs&&... args);
+
+ deferred(const deferred&) = default;
+ deferred(deferred&&) = default;
+ ~deferred(void) = default;
+ deferred& operator=(const deferred&) = default;
+ deferred& operator=(deferred&&) = default;
+
+ constexpr value_type value(void);
+ constexpr operator value_type(void);
+
+ private:
+ template
+ constexpr value_type get_value_(std::index_sequence);
+ };
+
+ template
+ class deferred_function
+ {
+ public:
+ using ret_t = decltype(std::declval()(std::declval()...));
+
+ private:
+ Fn m_fn;
+ std::tuple m_args;
+
+ public:
+ template
+ constexpr deferred_function(F&& f, FArgs&&... args);
+
+ constexpr decltype(auto) operator()(void);
+
+ constexpr decltype(auto) value(void);
+ constexpr operator ret_t(void);
+
+ private:
+ template
+ constexpr decltype(auto) get_value_(std::index_sequence);
+ };
+
+ template
+ template
+ constexpr deferred::deferred(FArgs&&... args):
+ m_args{std::forward(args)...}{}
+ template
+ constexpr auto deferred::value(void) -> value_type{
+ return get_value_(std::make_index_sequence());
+ }
+ template
+ constexpr deferred::operator value_type(void){
+ return get_value_(std::make_index_sequence());
+ }
+ template
+ template
+ constexpr auto deferred::get_value_(std::index_sequence) -> value_type{
+ return T{std::forward>(std::get(m_args))...};
+ }
+
+ template
+ template
+ constexpr deferred_function::deferred_function(F&& f, FArgs&&... args):
+ m_fn(std::forward(f)),
+ m_args{std::forward(args)...}{}
+
+ template
+ constexpr decltype(auto) deferred_function::operator()(void){
+ return get_value_(std::make_index_sequence());
+ }
+
+ template
+ constexpr decltype(auto) deferred_function::value(void){
+ return get_value_(std::make_index_sequence());
+ }
+ template
+ constexpr deferred_function::operator ret_t(void){
+ return get_value_(std::make_index_sequence());
+ }
+ template
+ template
+ constexpr decltype(auto) deferred_function::get_value_(std::index_sequence){
+ return std::forward(m_fn)(std::forward>(std::get(m_args))...);
+ }
+
+ template
+ deferred_function(Fn&&, Args&&...) -> deferred_function;
+
+
+ template
+ deferred make_deferred(Args&&... args){
+ return deferred(std::forward(args)...);
+ }
+
+}
+
+#endif
diff --git a/include/rexy/demangle.hpp b/include/rexy/demangle.hpp
new file mode 100644
index 0000000..7209662
--- /dev/null
+++ b/include/rexy/demangle.hpp
@@ -0,0 +1,29 @@
+/**
+ 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_UTIL_DEMANGLE_HPP
+#define REXY_UTIL_DEMANGLE_HPP
+
+#include
+
+namespace rexy{
+ std::string demangle(const char* name);
+}
+
+#endif
+
diff --git a/include/rexy/enum_traits.hpp b/include/rexy/enum_traits.hpp
new file mode 100644
index 0000000..6642388
--- /dev/null
+++ b/include/rexy/enum_traits.hpp
@@ -0,0 +1,204 @@
+/**
+ 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 .
+*/
+
+//requires c++20
+
+#ifndef REXY_ENUM_CLASS_HPP
+#define REXY_ENUM_CLASS_HPP
+
+#include
+
+template
+concept Scoped_Enum = requires{
+ typename std::underlying_type_t;
+ requires std::is_enum_v;
+ requires !std::is_convertible_v>;
+};
+
+
+//since std::to_underlying is only available since c++23
+namespace rexy::enum_traits{
+ template
+ constexpr std::underlying_type_t to_underlying(E t)noexcept{
+ return static_cast>(t);
+ }
+}
+
+template
+constexpr E operator|(E t, E t2)noexcept{
+ return static_cast(rexy::enum_traits::to_underlying(t) | rexy::enum_traits::to_underlying(t2));
+}
+template
+constexpr E& operator|=(E& t, E t2)noexcept{
+ t = static_cast(rexy::enum_traits::to_underlying(t) | rexy::enum_traits::to_underlying(t2));
+ return t;
+}
+template
+constexpr E operator&(E t, E t2)noexcept{
+ return static_cast(rexy::enum_traits::to_underlying(t) & rexy::enum_traits::to_underlying(t2));
+}
+template
+constexpr E& operator&=(E& t, E t2)noexcept{
+ t = static_cast(rexy::enum_traits::to_underlying(t) & rexy::enum_traits::to_underlying(t2));
+ return t;
+}
+template
+constexpr E operator^(E t, E t2)noexcept{
+ return static_cast(rexy::enum_traits::to_underlying(t) ^ rexy::enum_traits::to_underlying(t2));
+}
+template
+constexpr E& operator^=(E& t, E t2)noexcept{
+ t = static_cast(rexy::enum_traits::to_underlying(t) ^ rexy::enum_traits::to_underlying(t2));
+ return t;
+}
+template
+constexpr E operator!(E t)noexcept{
+ return static_cast(!(rexy::enum_traits::to_underlying(t)));
+}
+template
+constexpr E operator~(E t)noexcept{
+ return static_cast(~rexy::enum_traits::to_underlying(t));
+}
+template
+constexpr E operator<<(E t, int shift)noexcept{
+ return static_cast(rexy::enum_traits::to_underlying(t) << shift);
+}
+template
+constexpr E& operator<<=(E& t, int shift)noexcept{
+ t = static_cast(rexy::enum_traits::to_underlying(t) << shift);
+ return t;
+}
+template
+constexpr E operator>>(E t, int shift)noexcept{
+ return static_cast(rexy::enum_traits::to_underlying(t) >> shift);
+}
+template
+constexpr E& operator>>=(E& t, int shift)noexcept{
+ t = static_cast(rexy::enum_traits::to_underlying(t) >> shift);
+ return t;
+}
+
+template
+constexpr bool operator>(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) > rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator>(E t, std::underlying_type_t u){
+ return rexy::enum_traits::to_underlying(t) > u;
+}
+template
+constexpr bool operator<(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) < rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator<(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) < u;
+}
+template
+constexpr bool operator>=(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) >= rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator>=(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) >= u;
+}
+template
+constexpr bool operator<=(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) <= rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator<=(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) <= u;
+}
+template
+constexpr bool operator==(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) == rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator==(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) == u;
+}
+template
+constexpr bool operator!=(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) != rexy::enum_traits::to_underlying(t2);
+}
+template
+constexpr bool operator!=(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) != u;
+}
+
+namespace rexy::enum_traits{
+ template
+ constexpr bool not_zero(E t)noexcept{
+ return rexy::enum_traits::to_underlying(t) != 0;
+ }
+ template
+ constexpr bool is_zero(E t)noexcept{
+ return rexy::enum_traits::to_underlying(t) == 0;
+ }
+ template
+ constexpr bool is_greater_than(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) > rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_greater_than(E t, std::underlying_type_t u){
+ return rexy::enum_traits::to_underlying(t) > u;
+ }
+ template
+ constexpr bool is_less_than(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) < rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_less_than(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) < u;
+ }
+ template
+ constexpr bool is_greater_than_equal(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) >= rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_greater_than_equal(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) >= u;
+ }
+ template
+ constexpr bool is_less_than_equal(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) <= rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_less_than_equal(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) <= u;
+ }
+ template
+ constexpr bool is_equal(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) == rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_equal(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) == u;
+ }
+ template
+ constexpr bool is_not_equal(E t1, E t2)noexcept{
+ return rexy::enum_traits::to_underlying(t1) != rexy::enum_traits::to_underlying(t2);
+ }
+ template
+ constexpr bool is_not_equal(E t, std::underlying_type_t u)noexcept{
+ return rexy::enum_traits::to_underlying(t) != u;
+ }
+}
+
+#endif
diff --git a/include/rexy/source_location.hpp b/include/rexy/source_location.hpp
new file mode 100644
index 0000000..7567ea6
--- /dev/null
+++ b/include/rexy/source_location.hpp
@@ -0,0 +1,122 @@
+/**
+ 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_UTIL_SOURCE_LOCATION_HPP
+#define REXY_UTIL_SOURCE_LOCATION_HPP
+
+#include //feature test macro
+
+#ifndef __cpp_lib_source_location
+
+#include //uint_least32_t
+
+#if __cplusplus >= 202002L
+ #define CONSTEVAL consteval
+#else
+ #define CONSTEVAL constexpr
+#endif
+
+namespace rexy{
+
+ class source_location
+ {
+ private:
+ const char* m_file;
+ const char* m_func;
+ uint_least32_t m_line;
+ uint_least32_t m_column;
+
+ public:
+ constexpr source_location(void)noexcept;
+ constexpr source_location(const source_location&);
+ constexpr source_location(source_location&&)noexcept;
+
+ constexpr uint_least32_t line(void)const noexcept;
+ constexpr uint_least32_t column(void)const noexcept;
+ constexpr const char* file_name(void)const noexcept;
+ constexpr const char* function_name(void)const noexcept;
+
+ public:
+ #if (defined(__clang__) && (__clang_major__ >= 9)) || (defined(_MSC_VER) && (_MSC_VER >= 1926))
+ static CONSTEVAL source_location current(uint_least32_t line = __builtin_LINE(),
+ uint_least32_t col = __builtin_COLUMN(),
+ const char* file = __builtin_FILE(),
+ const char* func = __builtin_FUNCTION())noexcept;
+ #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
+ static CONSTEVAL source_location current(uint_least32_t line = __builtin_LINE(),
+ uint_least32_t col = 0,
+ const char* file = __builtin_FILE(),
+ const char* func = __builtin_FUNCTION())noexcept;
+ #else
+ static CONSTEVAL source_location current(uint_least32_t line = 0,
+ uint_least32_t col = 0,
+ const char* file = "unknown",
+ const char* func = "unknown")noexcept;
+ #endif
+
+ private:
+ constexpr source_location(uint_least32_t line, uint_least32_t col, const char* file, const char* func)noexcept;
+ };
+
+ constexpr source_location::source_location(void)noexcept:
+ source_location(0, 0, "unknown", "unknown"){}
+ constexpr source_location::source_location(const source_location& s):
+ source_location(s.m_line, s.m_column, s.m_file, s.m_func){}
+ constexpr source_location::source_location(source_location&& s)noexcept:
+ source_location(s.m_line, s.m_column, s.m_file, s.m_func){}
+ constexpr source_location::source_location(uint_least32_t line, uint_least32_t col, const char* file, const char* func)noexcept:
+ m_file(file),
+ m_func(func),
+ m_line(line),
+ m_column(col){}
+
+ constexpr uint_least32_t source_location::line(void)const noexcept{
+ return m_line;
+ }
+ constexpr uint_least32_t source_location::column(void)const noexcept{
+ return m_column;
+ }
+ constexpr const char* source_location::file_name(void)const noexcept{
+ return m_file;
+ }
+ constexpr const char* source_location::function_name(void)const noexcept{
+ return m_func;
+ }
+
+ CONSTEVAL source_location source_location::current(uint_least32_t line, uint_least32_t col, const char* file, const char* func)noexcept{
+ return source_location(line, col, file, func);
+ }
+
+}
+
+#undef CONSTEVAL
+
+#else //__cpp_lib_source_location
+
+#include
+
+namespace rexy{
+
+ using source_location = std::source_location;
+
+}
+
+#endif //__cpp_lib_source_location
+
+#endif
+
diff --git a/src/ensure.cpp b/src/ensure.cpp
index 1d1d19f..5ff17c5 100644
--- a/src/ensure.cpp
+++ b/src/ensure.cpp
@@ -19,6 +19,11 @@
#include "rexy/traits.hpp"
#include "rexy/utility.hpp"
#include "rexy/meta.hpp"
+#include "rexy/enum_traits.hpp"
+#include "rexy/deferred.hpp"
+#include "rexy/source_location.hpp"
+#include "rexy/demangle.hpp"
+#include "rexy/debug_print.hpp"
#include "rexy/detail/binary_string_conv.hpp"
#include "rexy/detail/string_appender.hpp"