diff options
Diffstat (limited to 'include/openvic-dataloader/detail/utility')
7 files changed, 212 insertions, 0 deletions
diff --git a/include/openvic-dataloader/detail/utility/Concepts.hpp b/include/openvic-dataloader/detail/utility/Concepts.hpp new file mode 100644 index 0000000..0ba91cc --- /dev/null +++ b/include/openvic-dataloader/detail/utility/Concepts.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include <concepts> +#include <cstdint> +#include <functional> +#include <utility> + +namespace ovdl { + struct NodeLocation; + struct File; + namespace detail { + enum class buffer_error : std::uint8_t; + } +} + +namespace ovdl::detail { + template<typename T, typename... Ts> + concept any_of = (std::same_as<T, Ts> || ...); + + template<typename T> + concept HasCstr = + requires(T t) { + { t.c_str() } -> std::same_as<const char*>; + }; + + template<typename T> + concept HasPath = requires(T& t) { + { t.path() } -> std::same_as<const char*>; + }; + + template<typename T, typename Self, typename... Args> + concept LoadCallback = + requires(T&& t, Self&& self, Args&&... args) { + { std::invoke(std::forward<T>(t), std::forward<Self>(self), std::forward<Args>(args)...) } -> std::same_as<ovdl::detail::buffer_error>; + }; + + template<typename T> + concept IsEncoding = requires(T t) { + typename T::char_type; + typename T::int_type; + { T::template is_secondary_char_type<typename T::char_type>() } -> std::same_as<bool>; + { T::eof() } -> std::same_as<typename T::int_type>; + { T::to_int_type(typename T::char_type {}) } -> std::same_as<typename T::int_type>; + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/utility/Constexpr.hpp b/include/openvic-dataloader/detail/utility/Constexpr.hpp new file mode 100644 index 0000000..49479c5 --- /dev/null +++ b/include/openvic-dataloader/detail/utility/Constexpr.hpp @@ -0,0 +1,15 @@ +#pragma once + +// THANK YOU APPLE FOR YOUR UTTER DISREGARD FOR C++20 + +#if __cpp_lib_optional >= 202106L +#define OVDL_OPTIONAL_CONSTEXPR constexpr +#else +#define OVDL_OPTIONAL_CONSTEXPR inline +#endif + +#if __cpp_lib_constexpr_vector >= 201907L +#define OVDL_VECTOR_CONSTEXPR constexpr +#else +#define OVDL_VECTOR_CONSTEXPR inline +#endif
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/utility/ErrorRange.hpp b/include/openvic-dataloader/detail/utility/ErrorRange.hpp new file mode 100644 index 0000000..a427f6c --- /dev/null +++ b/include/openvic-dataloader/detail/utility/ErrorRange.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <utility> + +#include <openvic-dataloader/Error.hpp> + +#include <dryad/node.hpp> + +namespace ovdl::detail { + using error_range = decltype(std::declval<const error::Root*>()->errors()); +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/utility/PointerHash.hpp b/include/openvic-dataloader/detail/utility/PointerHash.hpp new file mode 100644 index 0000000..c0d28bc --- /dev/null +++ b/include/openvic-dataloader/detail/utility/PointerHash.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include <cstdint> + +namespace ovdl::detail { + /* hash any pointer */ + template<typename T> + struct PointerHash { + using type = T; + using ptr_type = T*; + using const_type = const T; + using const_ptr_type = const T*; + using const_ptr_const_type = const const_ptr_type; + constexpr std::size_t operator()(const_ptr_const_type pointer) const { + auto addr = reinterpret_cast<uintptr_t>(pointer); +#if SIZE_MAX < UINTPTR_MAX + /* size_t is not large enough to hold the pointer’s memory address */ + addr %= SIZE_MAX; /* truncate the address so it is small enough to fit in a size_t */ +#endif + return addr; + } + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/utility/SelfType.hpp b/include/openvic-dataloader/detail/utility/SelfType.hpp new file mode 100644 index 0000000..5209700 --- /dev/null +++ b/include/openvic-dataloader/detail/utility/SelfType.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include <type_traits> + +namespace ovdl::detail { +#if !defined(_MSC_VER) +#pragma GCC diagnostic push +#pragma clang diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wnon-template-friend" +#endif + template<typename T> + struct Reader { + friend auto adl_GetSelfType(Reader<T>); + }; + + template<typename T, typename U> + struct Writer { + friend auto adl_GetSelfType(Reader<T>) { return U {}; } + }; +#if !defined(_MSC_VER) +#pragma GCC diagnostic pop +#endif + + inline void adl_GetSelfType() {} + + template<typename T> + using Read = std::remove_pointer_t<decltype(adl_GetSelfType(Reader<T> {}))>; +} diff --git a/include/openvic-dataloader/detail/utility/TypeName.hpp b/include/openvic-dataloader/detail/utility/TypeName.hpp new file mode 100644 index 0000000..1a34a0f --- /dev/null +++ b/include/openvic-dataloader/detail/utility/TypeName.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include <array> +#include <cstddef> +#include <string_view> +#include <utility> + +namespace ovdl::detail { + + template<std::size_t... Idxs> + constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>) { + return std::array { str[Idxs]... }; + } + + template<typename T> + constexpr auto type_name_array() { +#if defined(__clang__) + constexpr auto prefix = std::string_view { "[T = " }; + constexpr auto suffix = std::string_view { "]" }; + constexpr auto function = std::string_view { __PRETTY_FUNCTION__ }; +#elif defined(__GNUC__) + constexpr auto prefix = std::string_view { "with T = " }; + constexpr auto suffix = std::string_view { "]" }; + constexpr auto function = std::string_view { __PRETTY_FUNCTION__ }; +#elif defined(_MSC_VER) + constexpr auto prefix = std::string_view { "type_name_array<" }; + constexpr auto suffix = std::string_view { ">(void)" }; + constexpr auto function = std::string_view { __FUNCSIG__ }; +#else +#error Unsupported compiler +#endif + + constexpr auto start = function.find(prefix) + prefix.size(); + constexpr auto end = function.rfind(suffix); + + static_assert(start < end); + + constexpr auto name = function.substr(start, (end - start)); + return substring_as_array(name, std::make_index_sequence<name.size()> {}); + } + + template<typename T> + struct type_name_holder { + static inline constexpr auto value = type_name_array<T>(); + }; + + template<typename T> + constexpr auto type_name() -> std::string_view { + constexpr auto& value = type_name_holder<T>::value; + return std::string_view { value.data(), value.size() }; + } +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/utility/Utility.hpp b/include/openvic-dataloader/detail/utility/Utility.hpp new file mode 100644 index 0000000..138a029 --- /dev/null +++ b/include/openvic-dataloader/detail/utility/Utility.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include <string_view> +#include <type_traits> + +#include "openvic-dataloader/detail/utility/TypeName.hpp" + +namespace ovdl::detail { + [[noreturn]] inline void unreachable() { + // Uses compiler specific extensions if possible. + // Even if no extension is used, undefined behavior is still raised by + // an empty function body and the noreturn attribute. +#ifdef __GNUC__ // GCC, Clang, ICC + __builtin_unreachable(); +#elif defined(_MSC_VER) // MSVC + __assume(false); +#endif + } + + template<typename Kind> + constexpr std::string_view get_kind_name() { + constexpr auto name = type_name<Kind>(); + + return name; + } + + template<typename EnumT> + requires std::is_enum_v<EnumT> + constexpr std::underlying_type_t<EnumT> to_underlying(EnumT e) { + return static_cast<std::underlying_type_t<EnumT>>(e); + } + + template<typename EnumT> + requires std::is_enum_v<EnumT> + constexpr EnumT from_underlying(std::underlying_type_t<EnumT> ut) { + return static_cast<EnumT>(ut); + } +}
\ No newline at end of file |