blob: c6663e0dd145a18d2b2047a7ed6fbdbf75c9599a (
plain)
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
|
/**
* ForcedValue.h
*
* The ForcedValue is a wrapper around the value class that ensures that a
* certain property always has a certain type.
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
*/
/**
* Set up namespace
*/
namespace Php {
/**
* Class definition
*/
template <Type TYPE>
class ForcedValue : public Value
{
public:
/**
* Constructor
*/
ForcedValue() : Value() { setType(TYPE); }
/**
* Copy constructor
* @param that
*/
ForcedValue(const ForcedValue<TYPE> &that) : Value(that) {}
/**
* Move constructor
* @param that
*/
ForcedValue(ForcedValue<TYPE> &&that) : Value(std::move(that)) {}
/**
* Copy constructor from a value object
* @param value
*/
ForcedValue(const Value &value) : Value(value)
{
// type must be valid
if (value.type() != TYPE) throw Php::Exception("Assiging a wrong value type to a forced typed variable");
}
/**
* Wrap object around zval
* @param zval Zval to wrap
* @param ref Force this to be a reference
*/
ForcedValue(struct _zval_struct *zval, bool ref = false) : Value(zval, ref) { setType(TYPE); }
/**
* Destructor
*/
virtual ~ForcedValue() {}
/**
* Change the internal type of the variable
* @param Type
*/
virtual Value &setType(Type type) override
{
// throw exception if things are going wrong
if (type != TYPE) throw Php::Exception("Variable has a forced type");
// call base
return Value::setType(TYPE);
}
/**
* Assignment operator
* @param value
* @return ForcedValue
*/
ForcedValue<TYPE> &operator=(const Value &value)
{
// skip self assignment
if (this == &value) return *this;
// type must be valid
if (value.type() != TYPE) throw Php::Exception("Assiging a wrong value type to a forced typed variable");
// call base
Value::operator=(value);
// done
return *this;
}
/**
* Move assignment operator
* @param value
* @return ForcedValue
*/
ForcedValue<TYPE> &operator=(Value &&value)
{
// skip self assignment
if (this == &value) return *this;
// type must be valid
if (value.type() != TYPE) throw Php::Exception("Assiging a wrong value type to a forced typed variable");
// call base
Value::operator=(std::move(value));
// done
return *this;
}
protected:
/**
* Validate the object
* @return Value
*/
virtual Value &validate() override
{
// make sure the object has a valid type
setType(TYPE);
// call base
return Value::validate();
}
};
/**
* Define for arrays and objects
*/
using Array = ForcedValue<Type::Array>;
using Object = ForcedValue<Type::Object>;
/**
* End of namespace
*/
}
|