#pragma once #include #include #include #include namespace ovdl { template concept IsEncoding = requires(T t) { typename T::char_type; typename T::int_type; { T::template is_secondary_char_type() } -> std::same_as; { T::eof() } -> std::same_as; { T::to_int_type(typename T::char_type {}) } -> std::same_as; }; struct File { explicit File(const char* path); const char* path() const noexcept; protected: const char* _path; }; template concept IsFile = std::derived_from && IsEncoding && requires(T t, const typename T::node_type* node, NodeLocation location) { { t.buffer() } -> std::same_as&>; { t.set_location(node, location) } -> std::same_as; { t.location_of(node) } -> std::same_as; }; template struct BasicFile : File { using encoding_type = EncodingT; using node_type = NodeT; explicit BasicFile(const char* path, lexy::buffer&& buffer) : File(path), _buffer(static_cast&&>(buffer)) {} explicit BasicFile(lexy::buffer&& buffer) : File(""), _buffer(static_cast&&>(buffer)) {} const lexy::buffer& buffer() const { return _buffer; } void set_location(const node_type* n, NodeLocation loc) { _map.insert(n, loc); } NodeLocation location_of(const node_type* n) const { auto result = _map.lookup(n); DRYAD_ASSERT(result != nullptr, "every Node should have a NodeLocation"); return *result; } protected: lexy::buffer _buffer; dryad::node_map _map; }; }