#pragma once #include #include #include #include namespace ovdl { template concept IsParseState = requires( T t, const T ct, typename T::ast_type::file_type&& file, lexy::buffer&& buffer, const char* path // ) { requires IsAst; requires std::derived_from; { T { std::move(file) } } -> std::same_as; { T { std::move(buffer) } } -> std::same_as; { T { path, std::move(buffer) } } -> std::same_as; { t.ast() } -> std::same_as; { ct.ast() } -> std::same_as; { t.logger() } -> std::same_as; { ct.logger() } -> std::same_as; }; template struct ParseState { using ast_type = AstT; using diagnostic_logger_type = BasicDiagnosticLogger; ParseState(typename ast_type::file_type&& file) : _ast { std::move(file) }, _logger { _ast.file() } {} ParseState(lexy::buffer&& buffer) : ParseState(typename ast_type::file_type { std::move(buffer) }) {} ParseState(const char* path, lexy::buffer&& buffer) : ParseState(typename ast_type::file_type { path, std::move(buffer) }) {} ast_type& ast() { return _ast; } const ast_type& ast() const { return _ast; } diagnostic_logger_type& logger() { return _logger; } const diagnostic_logger_type& logger() const { return _logger; } private: ast_type _ast; diagnostic_logger_type _logger; }; template concept IsFileParseState = requires( T t, const T ct, typename T::file_type&& file, lexy::buffer&& buffer, const char* path // ) { requires IsFile; requires std::derived_from; { T { std::move(file) } } -> std::same_as; { T { std::move(buffer) } } -> std::same_as; { T { path, std::move(buffer) } } -> std::same_as; { t.file() } -> std::same_as; { ct.file() } -> std::same_as; { t.logger() } -> std::same_as; { ct.logger() } -> std::same_as; }; template struct FileParseState { using file_type = FileT; using diagnostic_logger_type = BasicDiagnosticLogger; FileParseState(file_type&& file) : _file { std::move(file) }, _logger { file } {} FileParseState(lexy::buffer&& buffer) : FileParseState(file_type { std::move(buffer) }) {} FileParseState(const char* path, lexy::buffer&& buffer) : FileParseState(file_type { path, std::move(buffer) }) {} file_type& file() { return _file; } const file_type& file() const { return _file; } diagnostic_logger_type& logger() { return _logger; } const diagnostic_logger_type& logger() const { return _logger; } private: file_type _file; diagnostic_logger_type _logger; }; }