aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-dataloader/ParseState.hpp
blob: a9a995341e0df15ef95b82adb0c559f7abeaa51e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#pragma once

#include <openvic-dataloader/detail/Encoding.hpp>

#include <lexy/encoding.hpp>
#include <lexy/input/buffer.hpp>

#include <dryad/tree.hpp>

#include "DiagnosticLogger.hpp"
#include "detail/InternalConcepts.hpp"

namespace ovdl {
   struct BasicParseState {
      explicit BasicParseState(detail::Encoding encoding = detail::Encoding::Unknown) : _encoding(encoding) {}

      detail::Encoding encoding() const {
         return _encoding;
      }

   protected:
      detail::Encoding _encoding;
   };

   template<detail::IsAst AstT>
   struct ParseState : BasicParseState {
      using ast_type = AstT;
      using file_type = typename ast_type::file_type;
      using diagnostic_logger_type = BasicDiagnosticLogger<ParseState>;

      ParseState() : _ast {}, _logger { this->ast().file() } {}

      ParseState(typename ast_type::file_type&& file, detail::Encoding encoding)
         : _ast { std::move(file) },
           _logger { this->ast().file() },
           BasicParseState(encoding) {}

      ParseState(ParseState&& other)
         : _ast { std::move(other._ast) },
           _logger { this->ast().file() },
           BasicParseState(other.encoding()) {}

      ParseState& operator=(ParseState&& rhs) {
         this->~ParseState();
         new (this) ParseState(std::move(rhs));

         return *this;
      }

      template<typename Encoding, typename MemoryResource = void>
      ParseState(lexy::buffer<Encoding, MemoryResource>&& buffer, detail::Encoding encoding)
         : ParseState(typename ast_type::file_type { std::move(buffer) }, encoding) {}

      template<typename Encoding, typename MemoryResource = void>
      ParseState(const char* path, lexy::buffer<Encoding, MemoryResource>&& buffer, detail::Encoding encoding)
         : ParseState(typename ast_type::file_type { path, std::move(buffer) }, encoding) {}

      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<detail::IsFile FileT>
   struct FileParseState : BasicParseState {
      using file_type = FileT;
      using diagnostic_logger_type = BasicDiagnosticLogger<FileParseState>;

      FileParseState() : _file {}, _logger { this->file() } {}

      FileParseState(file_type&& file, detail::Encoding encoding)
         : _file { std::move(file) },
           _logger { this->file() },
           BasicParseState(encoding) {}

      template<typename Encoding, typename MemoryResource = void>
      FileParseState(lexy::buffer<Encoding, MemoryResource>&& buffer, detail::Encoding encoding)
         : FileParseState(file_type { std::move(buffer) }, encoding) {}

      template<typename Encoding, typename MemoryResource = void>
      FileParseState(const char* path, lexy::buffer<Encoding, MemoryResource>&& buffer, detail::Encoding encoding)
         : FileParseState(file_type { path, std::move(buffer) }, encoding) {}

      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;
   };
}