diff options
Diffstat (limited to 'include/openvic-dataloader/detail')
15 files changed, 256 insertions, 88 deletions
diff --git a/include/openvic-dataloader/detail/BasicParser.hpp b/include/openvic-dataloader/detail/BasicParser.hpp deleted file mode 100644 index 7524bb5..0000000 --- a/include/openvic-dataloader/detail/BasicParser.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include <string> -#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; - std::string_view get_file_path() const; - - protected: - std::vector<ParseError> _errors; - std::vector<ParseWarning> _warnings; - - std::reference_wrapper<std::ostream> _error_stream; - std::string _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 index 641d53f..f7cfc4a 100644 --- a/include/openvic-dataloader/detail/CallbackOStream.hpp +++ b/include/openvic-dataloader/detail/CallbackOStream.hpp @@ -6,10 +6,10 @@ #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> { + template<typename Callback, class CharT, class traits = std::char_traits<CharT>> + class BasicCallbackStreamBuffer : public std::basic_streambuf<CharT, traits> { public: - using base_type = std::basic_streambuf<CHAR_T, traits>; + using base_type = std::basic_streambuf<CharT, traits>; using callback_type = Callback; using char_type = typename base_type::char_type; using int_type = typename base_type::int_type; @@ -29,11 +29,12 @@ namespace ovdl::detail { }; int_type overflow(int_type ch) override { + auto c = static_cast<char_type>(ch); if constexpr (std::is_same_v<void, typename decltype(std::function { _callback })::result_type>) { - _callback(&ch, 1, _user_data); + _callback(&c, 1, _user_data); return 1; } else { - return _callback(&ch, 1, _user_data); // returns the number of characters successfully written. + return _callback(&c, 1, _user_data); // returns the number of characters successfully written. } } @@ -64,22 +65,28 @@ namespace ovdl::detail { 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> { + template<class CharT, typename Callback, class traits = std::char_traits<CharT>> + class BasicCallbackStream : public std::basic_ostream<CharT, traits> { public: - using base_type = std::basic_ostream<CHAR_T, traits>; + using base_type = std::basic_ostream<CharT, 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); + std::basic_ios<CharT, traits>(&m_sbuf), + std::basic_ostream<CharT, traits>(&m_sbuf) { + std::basic_ios<CharT, traits>::init(&m_sbuf); } private: - BasicCallbackStreamBuffer<Callback, CHAR_T, traits> m_sbuf; + BasicCallbackStreamBuffer<Callback, CharT, traits> m_sbuf; }; + template<typename CharT> + auto make_callback_stream(auto&& cb, void* user_data = nullptr) { + using Callback = std::decay_t<decltype(cb)>; + return BasicCallbackStream<CharT, Callback> { std::forward<Callback>(cb), user_data }; + } + template<typename Callback> class CallbackStream : public BasicCallbackStream<Callback, char> { public: diff --git a/include/openvic-dataloader/detail/ClassExport.hpp b/include/openvic-dataloader/detail/ClassExport.hpp deleted file mode 100644 index 27098ed..0000000 --- a/include/openvic-dataloader/detail/ClassExport.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#ifdef _MSC_VER -#define OVDL_EXPORT __declspec(dllexport) -#elif defined(__GNUC__) -#define OVDL_EXPORT __attribute__((visibility("default"))) -#else -#define OVDL_EXPORT -#endif
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/Concepts.hpp b/include/openvic-dataloader/detail/Concepts.hpp deleted file mode 100644 index 3ca210c..0000000 --- a/include/openvic-dataloader/detail/Concepts.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include <concepts> -#include <optional> -#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/LexyFwdDeclaration.hpp b/include/openvic-dataloader/detail/LexyFwdDeclaration.hpp new file mode 100644 index 0000000..554c88d --- /dev/null +++ b/include/openvic-dataloader/detail/LexyFwdDeclaration.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace lexy { + struct default_encoding; + + template<typename Encoding, typename MemoryResource> + struct buffer; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/LexyReportError.hpp b/include/openvic-dataloader/detail/LexyReportError.hpp new file mode 100644 index 0000000..3c32bd1 --- /dev/null +++ b/include/openvic-dataloader/detail/LexyReportError.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include <cstddef> +#include <sstream> +#include <utility> +#include <vector> + +#include <openvic-dataloader/ParseData.hpp> +#include <openvic-dataloader/ParseError.hpp> + +#include <lexy/input_location.hpp> +#include <lexy/visualize.hpp> + +#include "openvic-dataloader/detail/utility/Concepts.hpp" + +#include <lexy_ext/report_error.hpp> + +namespace ovdl::detail { + template<typename OutputIterator> + struct _ReportError { + OutputIterator _iter; + lexy::visualization_options _opts; + const char* _path; + + struct _sink { + OutputIterator _iter; + lexy::visualization_options _opts; + const char* _path; + std::size_t _count; + std::vector<ParseError> _errors; + + using return_type = std::vector<ParseError>; + + template<typename Input, typename Reader, typename Tag> + void operator()(const lexy::error_context<Input>& context, const lexy::error<Reader, Tag>& error) { + _iter = lexy_ext::_detail::write_error(_iter, context, error, _opts, _path); + ++_count; + + // Convert the context location and error location into line/column information. + auto context_location = lexy::get_input_location(context.input(), context.position()); + auto location = lexy::get_input_location(context.input(), error.position(), context_location.anchor()); + + std::basic_stringstream<typename Reader::encoding::char_type> message; + + // Write the main annotation. + if constexpr (std::is_same_v<Tag, lexy::expected_literal>) { + auto string = lexy::_detail::make_literal_lexeme<typename Reader::encoding>(error.string(), error.length()); + + message << "expected '" << string.data() << '\''; + } else if constexpr (std::is_same_v<Tag, lexy::expected_keyword>) { + auto string = lexy::_detail::make_literal_lexeme<typename Reader::encoding>(error.string(), error.length()); + + message << "expected keyword '" << string.data() << '\''; + } else if constexpr (std::is_same_v<Tag, lexy::expected_char_class>) { + message << "expected " << error.name(); + } else { + message << error.message(); + } + + _errors.push_back( + ParseError { + ParseError::Type::Fatal, // TODO: distinguish recoverable errors from fatal errors + std::move(message.str()), + 0, // TODO: implement proper error codes + ParseData { + context.production(), + context_location.line_nr(), + context_location.column_nr(), + }, + location.line_nr(), + location.column_nr(), + }); + } + + return_type finish() && { + if (_count != 0) + *_iter++ = '\n'; + return _errors; + } + }; + constexpr auto sink() const { + return _sink { _iter, _opts, _path, 0 }; + } + + /// Specifies a path that will be printed alongside the diagnostic. + constexpr _ReportError path(const char* path) const { + return { _iter, _opts, path }; + } + + constexpr _ReportError path(const detail::HasCstr auto& path_object) const { + return path(path_object.c_str()); + } + + /// Specifies an output iterator where the errors are written to. + template<typename OI> + constexpr _ReportError<OI> to(OI out) const { + return { out, _opts, _path }; + } + + /// Overrides visualization options. + constexpr _ReportError opts(lexy::visualization_options opts) const { + return { _iter, opts, _path }; + } + }; + + constexpr auto ReporError = _ReportError<lexy::stderr_output_iterator> {}; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/OStreamOutputIterator.hpp b/include/openvic-dataloader/detail/OStreamOutputIterator.hpp new file mode 100644 index 0000000..8f120c7 --- /dev/null +++ b/include/openvic-dataloader/detail/OStreamOutputIterator.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include <memory> +#include <ostream> + +namespace ovdl::detail { + struct OStreamOutputIterator { + std::reference_wrapper<std::ostream> _stream; + + auto operator*() const noexcept { + return *this; + } + auto operator++(int) const noexcept { + return *this; + } + + OStreamOutputIterator& operator=(char c) { + _stream.get().put(c); + return *this; + } + }; +}
\ No newline at end of file diff --git a/include/openvic-dataloader/detail/OptionalConstexpr.hpp b/include/openvic-dataloader/detail/OptionalConstexpr.hpp deleted file mode 100644 index bcb12a7..0000000 --- a/include/openvic-dataloader/detail/OptionalConstexpr.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#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
\ No newline at end of file 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/VectorConstexpr.hpp b/include/openvic-dataloader/detail/utility/Constexpr.hpp index 7e7fa34..49479c5 100644 --- a/include/openvic-dataloader/detail/VectorConstexpr.hpp +++ b/include/openvic-dataloader/detail/utility/Constexpr.hpp @@ -2,6 +2,12 @@ // 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 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/PointerHash.hpp b/include/openvic-dataloader/detail/utility/PointerHash.hpp index c0d28bc..c0d28bc 100644 --- a/include/openvic-dataloader/detail/PointerHash.hpp +++ b/include/openvic-dataloader/detail/utility/PointerHash.hpp diff --git a/include/openvic-dataloader/detail/SelfType.hpp b/include/openvic-dataloader/detail/utility/SelfType.hpp index 5209700..5209700 100644 --- a/include/openvic-dataloader/detail/SelfType.hpp +++ b/include/openvic-dataloader/detail/utility/SelfType.hpp diff --git a/include/openvic-dataloader/detail/TypeName.hpp b/include/openvic-dataloader/detail/utility/TypeName.hpp index 1a34a0f..1a34a0f 100644 --- a/include/openvic-dataloader/detail/TypeName.hpp +++ b/include/openvic-dataloader/detail/utility/TypeName.hpp 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 |