summary refs log tree commit diff stats
path: root/lib/binding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/binding.cpp')
-rw-r--r--lib/binding.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/lib/binding.cpp b/lib/binding.cpp new file mode 100644 index 0000000..349cd6f --- /dev/null +++ b/lib/binding.cpp
@@ -0,0 +1,180 @@
1#include "binding.h"
2#include <stdexcept>
3#include <utility>
4
5namespace verbly {
6
7 binding::binding(const binding& other)
8 {
9 type_ = other.type_;
10
11 switch (type_)
12 {
13 case type::integer:
14 {
15 integer_ = other.integer_;
16
17 break;
18 }
19
20 case type::string:
21 {
22 new(&string_) std::string(other.string_);
23
24 break;
25 }
26
27 case type::invalid:
28 {
29 break;
30 }
31 }
32 }
33
34 binding::binding(binding&& other) : binding()
35 {
36 swap(*this, other);
37 }
38
39 binding& binding::operator=(binding other)
40 {
41 swap(*this, other);
42
43 return *this;
44 }
45
46 void swap(binding& first, binding& second)
47 {
48 using type = binding::type;
49
50 type tempType = first.type_;
51 int tempInteger;
52 std::string tempString;
53
54 switch (first.type_)
55 {
56 case type::integer:
57 {
58 tempInteger = first.integer_;
59
60 break;
61 }
62
63 case type::string:
64 {
65 tempString = std::move(tempString);
66
67 break;
68 }
69
70 case type::invalid:
71 {
72 break;
73 }
74 }
75
76 first.~binding();
77
78 first.type_ = second.type_;
79
80 switch (second.type_)
81 {
82 case type::integer:
83 {
84 first.integer_ = second.integer_;
85
86 break;
87 }
88
89 case type::string:
90 {
91 new(&first.string_) std::string(std::move(second.string_));
92
93 break;
94 }
95
96 case type::invalid:
97 {
98 break;
99 }
100 }
101
102 second.~binding();
103
104 second.type_ = tempType;
105
106 switch (tempType)
107 {
108 case type::integer:
109 {
110 second.integer_ = tempInteger;
111
112 break;
113 }
114
115 case type::string:
116 {
117 new(&second.string_) std::string(std::move(tempString));
118
119 break;
120 }
121
122 case type::invalid:
123 {
124 break;
125 }
126 }
127 }
128
129 binding::~binding()
130 {
131 switch (type_)
132 {
133 case type::string:
134 {
135 using string_type = std::string;
136 string_.~string_type();
137
138 break;
139 }
140
141 case type::integer:
142 case type::invalid:
143 {
144 break;
145 }
146 }
147 }
148
149 binding::binding(int arg) :
150 type_(type::integer),
151 integer_(arg)
152 {
153 }
154
155 int binding::getInteger() const
156 {
157 if (type_ != type::integer)
158 {
159 throw std::domain_error("binding::getInteger called on non-integer binding");
160 }
161
162 return integer_;
163 }
164
165 binding::binding(std::string arg) : type_(type::string)
166 {
167 new(&string_) std::string(arg);
168 }
169
170 std::string binding::getString() const
171 {
172 if (type_ != type::string)
173 {
174 throw std::domain_error("binding::getString called on non-string binding");
175 }
176
177 return string_;
178 }
179
180};