Add some types I've made over the last month or so from other projects
This commit is contained in:
parent
ffcd4962fe
commit
8a3b5045cd
@ -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}
|
||||
|
||||
155
include/rexy/debug_print.hpp
Normal file
155
include/rexy/debug_print.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 <cstdio> //fprintf, vfprintf
|
||||
#include <utility> //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<class... Args>
|
||||
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>(args)...);
|
||||
}
|
||||
print(const print&) = delete;
|
||||
print(print&&) = delete;
|
||||
print& operator=(const print&) = delete;
|
||||
print& operator=(print&&) = delete;
|
||||
};
|
||||
template<class... Args>
|
||||
print(Args&&...) -> print<Args&&...>;
|
||||
#ifdef REXY_ENABLE_COLOR_DEBUG
|
||||
template<class... Args>
|
||||
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>(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<class... Args>
|
||||
print_info(Args&&...) -> print_info<Args&&...>;
|
||||
template<class... Args>
|
||||
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>(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<class... Args>
|
||||
print_warn(Args&&...) -> print_warn<Args&&...>;
|
||||
template<class... Args>
|
||||
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>(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<class... Args>
|
||||
print_error(Args&&...) -> print_error<Args&&...>;
|
||||
#else
|
||||
template<class... Args>
|
||||
using print_info = print<Args...>;
|
||||
template<class... Args>
|
||||
using print_warn = print<Args...>;
|
||||
template<class... Args>
|
||||
using print_error = print<Args...>;
|
||||
#endif //REXY_ENABLE_COLOR_DEBUG
|
||||
|
||||
#ifdef REXY_ENABLE_DEBUG_VERBOSE_OUTPUT
|
||||
namespace verbose{
|
||||
template<class... Args>
|
||||
using print = rexy::debug::print<Args...>;
|
||||
template<class... Args>
|
||||
using print_info = rexy::debug::print_info<Args...>;
|
||||
template<class... Args>
|
||||
using print_warn = rexy::debug::print_warn<Args...>;
|
||||
template<class... Args>
|
||||
using print_error = rexy::debug::print_error<Args...>;
|
||||
}
|
||||
#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
|
||||
131
include/rexy/deferred.hpp
Normal file
131
include/rexy/deferred.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_UTIL_DEFERRED_HPP
|
||||
#define REXY_UTIL_DEFERRED_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <utility> //forward, index_sequence
|
||||
|
||||
namespace rexy{
|
||||
template<class T, class... Args>
|
||||
class deferred
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
private:
|
||||
std::tuple<Args&&...> m_args;
|
||||
|
||||
public:
|
||||
template<class... FArgs>
|
||||
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<size_t... Is>
|
||||
constexpr value_type get_value_(std::index_sequence<Is...>);
|
||||
};
|
||||
|
||||
template<class Fn, class... Args>
|
||||
class deferred_function
|
||||
{
|
||||
public:
|
||||
using ret_t = decltype(std::declval<Fn>()(std::declval<Args>()...));
|
||||
|
||||
private:
|
||||
Fn m_fn;
|
||||
std::tuple<Args&&...> m_args;
|
||||
|
||||
public:
|
||||
template<class F, class... FArgs>
|
||||
constexpr deferred_function(F&& f, FArgs&&... args);
|
||||
|
||||
constexpr decltype(auto) operator()(void);
|
||||
|
||||
constexpr decltype(auto) value(void);
|
||||
constexpr operator ret_t(void);
|
||||
|
||||
private:
|
||||
template<size_t... Is>
|
||||
constexpr decltype(auto) get_value_(std::index_sequence<Is...>);
|
||||
};
|
||||
|
||||
template<class T, class... Args>
|
||||
template<class... FArgs>
|
||||
constexpr deferred<T,Args...>::deferred(FArgs&&... args):
|
||||
m_args{std::forward<FArgs>(args)...}{}
|
||||
template<class T, class... Args>
|
||||
constexpr auto deferred<T,Args...>::value(void) -> value_type{
|
||||
return get_value_(std::make_index_sequence<sizeof...(Args)>());
|
||||
}
|
||||
template<class T, class... Args>
|
||||
constexpr deferred<T,Args...>::operator value_type(void){
|
||||
return get_value_(std::make_index_sequence<sizeof...(Args)>());
|
||||
}
|
||||
template<class T, class... Args>
|
||||
template<size_t... Is>
|
||||
constexpr auto deferred<T,Args...>::get_value_(std::index_sequence<Is...>) -> value_type{
|
||||
return T{std::forward<std::tuple_element_t<Is,decltype(m_args)>>(std::get<Is>(m_args))...};
|
||||
}
|
||||
|
||||
template<class Fn, class... Args>
|
||||
template<class F, class... FArgs>
|
||||
constexpr deferred_function<Fn,Args...>::deferred_function(F&& f, FArgs&&... args):
|
||||
m_fn(std::forward<F>(f)),
|
||||
m_args{std::forward<FArgs>(args)...}{}
|
||||
|
||||
template<class Fn, class... Args>
|
||||
constexpr decltype(auto) deferred_function<Fn,Args...>::operator()(void){
|
||||
return get_value_(std::make_index_sequence<sizeof...(Args)>());
|
||||
}
|
||||
|
||||
template<class Fn, class... Args>
|
||||
constexpr decltype(auto) deferred_function<Fn,Args...>::value(void){
|
||||
return get_value_(std::make_index_sequence<sizeof...(Args)>());
|
||||
}
|
||||
template<class Fn, class... Args>
|
||||
constexpr deferred_function<Fn,Args...>::operator ret_t(void){
|
||||
return get_value_(std::make_index_sequence<sizeof...(Args)>());
|
||||
}
|
||||
template<class Fn, class... Args>
|
||||
template<size_t... Is>
|
||||
constexpr decltype(auto) deferred_function<Fn,Args...>::get_value_(std::index_sequence<Is...>){
|
||||
return std::forward<Fn>(m_fn)(std::forward<std::tuple_element_t<Is,decltype(m_args)>>(std::get<Is>(m_args))...);
|
||||
}
|
||||
|
||||
template<class Fn, class... Args>
|
||||
deferred_function(Fn&&, Args&&...) -> deferred_function<Fn&&, Args&&...>;
|
||||
|
||||
|
||||
template<class T, class... Args>
|
||||
deferred<T,Args...> make_deferred(Args&&... args){
|
||||
return deferred<T,Args...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
29
include/rexy/demangle.hpp
Normal file
29
include/rexy/demangle.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_UTIL_DEMANGLE_HPP
|
||||
#define REXY_UTIL_DEMANGLE_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace rexy{
|
||||
std::string demangle(const char* name);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
204
include/rexy/enum_traits.hpp
Normal file
204
include/rexy/enum_traits.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//requires c++20
|
||||
|
||||
#ifndef REXY_ENUM_CLASS_HPP
|
||||
#define REXY_ENUM_CLASS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template<class T>
|
||||
concept Scoped_Enum = requires{
|
||||
typename std::underlying_type_t<T>;
|
||||
requires std::is_enum_v<T>;
|
||||
requires !std::is_convertible_v<T, std::underlying_type_t<T>>;
|
||||
};
|
||||
|
||||
|
||||
//since std::to_underlying is only available since c++23
|
||||
namespace rexy::enum_traits{
|
||||
template<Scoped_Enum E>
|
||||
constexpr std::underlying_type_t<E> to_underlying(E t)noexcept{
|
||||
return static_cast<std::underlying_type_t<E>>(t);
|
||||
}
|
||||
}
|
||||
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator|(E t, E t2)noexcept{
|
||||
return static_cast<E>(rexy::enum_traits::to_underlying(t) | rexy::enum_traits::to_underlying(t2));
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E& operator|=(E& t, E t2)noexcept{
|
||||
t = static_cast<E>(rexy::enum_traits::to_underlying(t) | rexy::enum_traits::to_underlying(t2));
|
||||
return t;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator&(E t, E t2)noexcept{
|
||||
return static_cast<E>(rexy::enum_traits::to_underlying(t) & rexy::enum_traits::to_underlying(t2));
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E& operator&=(E& t, E t2)noexcept{
|
||||
t = static_cast<E>(rexy::enum_traits::to_underlying(t) & rexy::enum_traits::to_underlying(t2));
|
||||
return t;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator^(E t, E t2)noexcept{
|
||||
return static_cast<E>(rexy::enum_traits::to_underlying(t) ^ rexy::enum_traits::to_underlying(t2));
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E& operator^=(E& t, E t2)noexcept{
|
||||
t = static_cast<E>(rexy::enum_traits::to_underlying(t) ^ rexy::enum_traits::to_underlying(t2));
|
||||
return t;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator!(E t)noexcept{
|
||||
return static_cast<E>(!(rexy::enum_traits::to_underlying(t)));
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator~(E t)noexcept{
|
||||
return static_cast<E>(~rexy::enum_traits::to_underlying(t));
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator<<(E t, int shift)noexcept{
|
||||
return static_cast<E>(rexy::enum_traits::to_underlying(t) << shift);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E& operator<<=(E& t, int shift)noexcept{
|
||||
t = static_cast<E>(rexy::enum_traits::to_underlying(t) << shift);
|
||||
return t;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E operator>>(E t, int shift)noexcept{
|
||||
return static_cast<E>(rexy::enum_traits::to_underlying(t) >> shift);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr E& operator>>=(E& t, int shift)noexcept{
|
||||
t = static_cast<E>(rexy::enum_traits::to_underlying(t) >> shift);
|
||||
return t;
|
||||
}
|
||||
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator>(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) > rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator>(E t, std::underlying_type_t<E> u){
|
||||
return rexy::enum_traits::to_underlying(t) > u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator<(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) < rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator<(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) < u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator>=(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) >= rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator>=(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) >= u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator<=(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) <= rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator<=(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) <= u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator==(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) == rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator==(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) == u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator!=(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) != rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool operator!=(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) != u;
|
||||
}
|
||||
|
||||
namespace rexy::enum_traits{
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool not_zero(E t)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) != 0;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_zero(E t)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) == 0;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_greater_than(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) > rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_greater_than(E t, std::underlying_type_t<E> u){
|
||||
return rexy::enum_traits::to_underlying(t) > u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_less_than(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) < rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_less_than(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) < u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
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<Scoped_Enum E>
|
||||
constexpr bool is_greater_than_equal(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) >= u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
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<Scoped_Enum E>
|
||||
constexpr bool is_less_than_equal(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) <= u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_equal(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) == rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_equal(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) == u;
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_not_equal(E t1, E t2)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t1) != rexy::enum_traits::to_underlying(t2);
|
||||
}
|
||||
template<Scoped_Enum E>
|
||||
constexpr bool is_not_equal(E t, std::underlying_type_t<E> u)noexcept{
|
||||
return rexy::enum_traits::to_underlying(t) != u;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
122
include/rexy/source_location.hpp
Normal file
122
include/rexy/source_location.hpp
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REXY_UTIL_SOURCE_LOCATION_HPP
|
||||
#define REXY_UTIL_SOURCE_LOCATION_HPP
|
||||
|
||||
#include <version> //feature test macro
|
||||
|
||||
#ifndef __cpp_lib_source_location
|
||||
|
||||
#include <cstdint> //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 <source_location>
|
||||
|
||||
namespace rexy{
|
||||
|
||||
using source_location = std::source_location;
|
||||
|
||||
}
|
||||
|
||||
#endif //__cpp_lib_source_location
|
||||
|
||||
#endif
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user