diff options
Diffstat (limited to 'include/openvic-dataloader/detail')
-rw-r--r-- | include/openvic-dataloader/detail/BasicParser.hpp | 37 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/CallbackOStream.hpp | 100 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/Concepts.hpp | 22 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/SelfType.hpp | 28 | ||||
-rw-r--r-- | include/openvic-dataloader/detail/TypeName.hpp | 52 |
5 files changed, 239 insertions, 0 deletions
diff --git a/include/openvic-dataloader/detail/BasicParser.hpp b/include/openvic-dataloader/detail/BasicParser.hpp new file mode 100644 index 0000000..5493804 --- /dev/null +++ b/include/openvic-dataloader/detail/BasicParser.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <filesystem> +#include <optional> +#include <string_view> +#include <vector> + +#include <openvic-dataloader/ParseError.hpp> +#include <openvic-dataloader/ParseWarning.hpp> +#include <openvic-dataloader/detail/Concepts.hpp> + +namespace ovdl::detail { + class BasicParser { + public: + BasicParser(); + + void set_error_log_to_null(); + void set_error_log_to_stderr(); + void set_error_log_to_stdout(); + void set_error_log_to(std::basic_ostream<char>& stream); + + bool has_error() const; + bool has_fatal_error() const; + bool has_warning() const; + + const std::vector<ParseError>& get_errors() const; + const std::vector<ParseWarning>& get_warnings() const; + + protected: + std::vector<ParseError> _errors; + std::vector<ParseWarning> _warnings; + + std::reference_wrapper<std::ostream> _error_stream; + const char* _file_path; + bool _has_fatal_error = false; + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/CallbackOStream.hpp b/include/openvic-dataloader/detail/CallbackOStream.hpp new file mode 100644 index 0000000..641d53f --- /dev/null +++ b/include/openvic-dataloader/detail/CallbackOStream.hpp @@ -0,0 +1,100 @@ +#pragma once + +#include <cstring> +#include <functional> +#include <ostream> +#include <type_traits> + +namespace ovdl::detail { + template<typename Callback, class CHAR_T, class traits = std::char_traits<CHAR_T>> + class BasicCallbackStreamBuffer : public std::basic_streambuf<CHAR_T, traits> { + public: + using base_type = std::basic_streambuf<CHAR_T, traits>; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + BasicCallbackStreamBuffer(Callback cb, void* user_data = nullptr) + : _callback(cb), + _user_data(user_data) {} + + protected: + std::streamsize xsputn(const char_type* s, std::streamsize n) override { + if constexpr (std::is_same_v<void, typename decltype(std::function { _callback })::result_type>) { + _callback(s, n, _user_data); + return n; + } else { + return _callback(s, n, _user_data); // returns the number of characters successfully written. + } + }; + + int_type overflow(int_type ch) override { + if constexpr (std::is_same_v<void, typename decltype(std::function { _callback })::result_type>) { + _callback(&ch, 1, _user_data); + return 1; + } else { + return _callback(&ch, 1, _user_data); // returns the number of characters successfully written. + } + } + + private: + Callback _callback; + void* _user_data; + }; + + template<typename Callback> + class CallbackStreamBuffer : public BasicCallbackStreamBuffer<Callback, char> { + public: + using base_type = BasicCallbackStreamBuffer<Callback, char>; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + CallbackStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} + }; + + template<typename Callback> + class CallbackWStreamBuffer : public BasicCallbackStreamBuffer<Callback, wchar_t> { + public: + using base_type = BasicCallbackStreamBuffer<Callback, wchar_t>; + using callback_type = Callback; + using char_type = typename base_type::char_type; + using int_type = typename base_type::int_type; + + CallbackWStreamBuffer(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) {} + }; + + template<typename Callback, class CHAR_T, class traits = std::char_traits<CHAR_T>> + class BasicCallbackStream : public std::basic_ostream<CHAR_T, traits> { + public: + using base_type = std::basic_ostream<CHAR_T, traits>; + + BasicCallbackStream(Callback cb, void* user_data = nullptr) + : m_sbuf(cb, user_data), + std::basic_ios<CHAR_T, traits>(&m_sbuf), + std::basic_ostream<CHAR_T, traits>(&m_sbuf) { + std::basic_ios<CHAR_T, traits>::init(&m_sbuf); + } + + private: + BasicCallbackStreamBuffer<Callback, CHAR_T, traits> m_sbuf; + }; + + template<typename Callback> + class CallbackStream : public BasicCallbackStream<Callback, char> { + public: + using base_type = BasicCallbackStream<Callback, char>; + + CallbackStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { + } + }; + + template<typename Callback> + class CallbackWStream : public BasicCallbackStream<Callback, wchar_t> { + public: + using base_type = BasicCallbackStream<Callback, wchar_t>; + + CallbackWStream(Callback cb, void* user_data = nullptr) : base_type(cb, user_data) { + } + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/Concepts.hpp b/include/openvic-dataloader/detail/Concepts.hpp new file mode 100644 index 0000000..3e1c785 --- /dev/null +++ b/include/openvic-dataloader/detail/Concepts.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include <concepts> +#include <optional> +#include <type_traits> +#include <utility> + +#include <openvic-dataloader/ParseError.hpp> + +namespace ovdl::detail { + template<typename T, typename Self, typename... Args> + concept LoadCallback = + requires(T t, Self* self, Args... args) { + { t(self, std::forward<Args>(args)...) } -> std::same_as<std::optional<ParseError>>; + }; + + template<typename T> + concept Has_c_str = + requires(T t) { + { t.c_str() } -> std::same_as<const char*>; + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/SelfType.hpp b/include/openvic-dataloader/detail/SelfType.hpp new file mode 100644 index 0000000..5209700 --- /dev/null +++ b/include/openvic-dataloader/detail/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/TypeName.hpp b/include/openvic-dataloader/detail/TypeName.hpp new file mode 100644 index 0000000..1a34a0f --- /dev/null +++ b/include/openvic-dataloader/detail/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 |