aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-dataloader/ParseState.hpp
blob: 6d635ee02f0acef5753cb7a286f41bc7ac92b649 (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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#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) {}

      FileParseState(const FileParseState&) = delete;
      FileParseState& operator=(const FileParseState&) = delete;

      FileParseState(FileParseState&& other)
         : _file { std::move(other._file) },
           _logger { this->file() },
           BasicParseState(std::move(other)) {}

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

         return *this;
      }

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