summary refs log tree commit diff stats
path: root/generator/part.h
blob: 550f95fcbae7af2912398223063f58677ea4fe59 (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
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef PART_H_FB54F361
#define PART_H_FB54F361

#include <string>
#include <set>
#include <variant>
#include "../lib/enums.h"

namespace verbly {

  namespace generator {

    class part {
    public:

      using type = part_type;

      // Static factories

      static part createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs);

      static part createVerb();

      static part createPreposition(std::set<std::string> choices, bool literal);

      static part createAdjective();

      static part createAdverb();

      static part createLiteral(std::string value);

      // Duplication

      static part duplicate(const part& other);

      // General accessors

      int getId() const
      {
        return id_;
      }

      type getType() const
      {
        return type_;
      }

      // Noun phrase accessors

      std::string getNounRole() const;

      std::set<std::string> getNounSelrestrs() const;

      std::set<std::string> getNounSynrestrs() const;

      // Preposition accessors

      std::set<std::string> getPrepositionChoices() const;

      bool isPrepositionLiteral() const;

      // Literal accessors

      std::string getLiteralValue() const;

    private:

      struct noun_phrase_type {
        std::string role;
        std::set<std::string> selrestrs;
        std::set<std::string> synrestrs;
      };

      struct preposition_type {
        std::set<std::string> choices;
        bool literal;
      };

      using literal_type = std::string;

      using variant_type =
        std::variant<
          std::monostate,
          noun_phrase_type,
          preposition_type,
          literal_type>;

      static int nextId_;

      int id_;

      // Private constructors

      part()
      {
      }

      part(type t, variant_type variant = {}) :
        id_(nextId_++),
        type_(t),
        variant_(std::move(variant))
      {
        bool valid_type = false;
        switch (type_)
        {
          case part_type::noun_phrase:
          {
            valid_type = std::holds_alternative<noun_phrase_type>(variant_);
            break;
          }
          case part_type::preposition:
          {
            valid_type = std::holds_alternative<preposition_type>(variant_);
            break;
          }
          case part_type::literal:
          {
            valid_type = std::holds_alternative<literal_type>(variant_);
            break;
          }
          case part_type::invalid:
          case part_type::verb:
          case part_type::adjective:
          case part_type::adverb:
          {
            valid_type = std::holds_alternative<std::monostate>(variant_);
            break;
          }
        }
        if (!valid_type)
        {
          throw std::invalid_argument("Invalid variant provided for part");
        }
      }

      // Data

      variant_type variant_;

      type type_ = type::invalid;

    };

  };
};

#endif /* end of include guard: PART_H_FB54F361 */