varconf 1.0.3
Configuration library for the Worldforge system.
variable.h
1/*
2 * variable.h - interface for typeless value container class
3 * Copyright (C) 2001, Stefanus Du Toit, Joseph Zupko
4 * (C) 2001-2006 Alistair Riddoch
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 * Contact: Joseph Zupko
21 * jaz147@psu.edu
22 *
23 * 189 Reese St.
24 * Old Forge, PA 18518
25 */
26
27#ifndef VARCONF_VARIABLE_H
28#define VARCONF_VARIABLE_H
29
30#include "varconf_defs.h"
31
32#include <sigc++/trackable.h>
33
34#include <string>
35#include <iostream>
36#include <vector>
37
38namespace varconf {
39
40typedef enum { GLOBAL = 0x1u << 0u,
41 USER = 0x1u << 1u,
42 INSTANCE = 0x1u << 2u
43} Scope;
44
45class VARCONF_API VarBase : virtual public sigc::trackable {
46public:
47 VarBase();
48 VarBase(const VarBase& c);
49 VarBase(bool b);
50 VarBase(int i);
51 VarBase(double d);
52 VarBase(std::string s);
53 VarBase(const char* s);
54
55 virtual ~VarBase();
56
57 VARCONF_API friend std::ostream& operator<<(std::ostream& out, const VarBase& v);
58 VARCONF_API friend bool operator ==(const VarBase& one, const VarBase& two);
59 VARCONF_API friend bool operator !=(const VarBase& one, const VarBase& two);
60
61 VarBase& operator=(const VarBase& c);
62 virtual VarBase& operator=(bool b);
63 virtual VarBase& operator=(int i);
64 virtual VarBase& operator=(double d);
65 virtual VarBase& operator=(const std::string& s);
66 virtual VarBase& operator=(const char* s);
67
68 virtual explicit operator bool() const;
69 virtual explicit operator int() const;
70 virtual explicit operator double() const;
71 virtual explicit operator std::string() const;
72
73 virtual bool is_bool();
74 virtual bool is_int();
75 virtual bool is_double();
76 virtual bool is_string();
77
78 Scope scope() const { return m_scope; }
79
80 void setScope(Scope s) { m_scope = s; }
81private:
82 mutable bool m_have_bool;
83 mutable bool m_have_int;
84 mutable bool m_have_double;
85 bool m_have_string;
86
87 mutable bool m_val_bool;
88 mutable int m_val_int;
89 mutable double m_val_double;
90 std::string m_val;
91
92protected:
93 Scope m_scope;
94};
95
96VARCONF_API std::ostream& operator<<(std::ostream& out, const VarBase& v);
97VARCONF_API bool operator ==(const VarBase& one, const VarBase& two);
98
99// The next two classes manage a reference count to
100// a pointer to class VarBase.
101
103{
104 public:
105 VarBox(VarBase *vb) : m_var(vb), m_ref(1) {}
106 ~VarBox() {delete m_var;}
107
108 void ref() {++m_ref;}
109 void unref() {if(--m_ref == 0) delete this;}
110
111 VarBase *elem() {return m_var;}
112
113 VarBox(const VarBox&) = delete;
114 VarBox& operator=(const VarBox&) = delete;
115private:
116
117 VarBase *m_var;
118 unsigned long m_ref;
119};
120
121class VARCONF_API VarPtr
122{
123 public:
124 VarPtr(VarBase *vb) : m_box(new VarBox(vb)) {}
125 VarPtr(const VarPtr &vp) : m_box(vp.m_box) {m_box->ref();}
126 ~VarPtr() {m_box->unref();}
127
128 VarPtr& operator=(const VarPtr &vp)
129 {
130 if(vp.m_box != m_box) {
131 m_box->unref();
132 m_box = vp.m_box;
133 m_box->ref();
134 }
135
136 return *this;
137 }
138
139 VarBase& elem() const {return *m_box->elem();}
140 VarBase* operator->() const {return m_box->elem();}
141
142 private:
143 VarBox *m_box;
144};
145
146class Variable;
147typedef std::vector<Variable> VarList;
148
149class VARCONF_API Variable : public VarPtr {
150public:
151 Variable() : VarPtr(new VarBase()) {}
152 Variable(const Variable& c);
153 Variable(VarBase* vb) : VarPtr(vb) {}
154 Variable(bool b) : VarPtr(new VarBase(b)) {}
155 Variable(int i) : VarPtr(new VarBase(i)) {}
156 Variable(double d) : VarPtr(new VarBase(d)) {}
157 Variable(const std::string& s) : VarPtr(new VarBase(s)) {}
158 Variable(const char* s) : VarPtr(new VarBase(s)) {}
159 Variable(int n, const Variable& v);
160 Variable(const VarList& v);
161
162 virtual ~Variable();
163
164 friend std::ostream& operator<<(std::ostream& out, const Variable& v)
165 {return (out << v.elem());}
166 friend bool operator ==(const Variable& one, const Variable& two)
167 {return (one.elem() == two.elem());}
168 friend bool operator !=(const Variable& one, const Variable& two)
169 {return (one.elem() != two.elem());}
170
171 Variable& operator=(const Variable& c);
172 Variable& operator=(VarBase* vb);
173 Variable& operator=(bool b);
174 Variable& operator=(int i);
175 Variable& operator=(double d);
176 Variable& operator=(const std::string& s);
177 Variable& operator=(const char* s);
178 Variable& operator=(const VarList& v);
179
180 explicit operator bool() const {return bool(this->elem());}
181 explicit operator int() const {return int(this->elem());}
182 explicit operator double() const {return double(this->elem());}
183 explicit operator std::string() const {return std::string(this->elem());}
184 VarList* array() const {return dynamic_cast<VarList*>(&this->elem());}
185 Variable& operator[](int i);
186
187 std::string as_string() const {return std::string(this->elem());}
188
189 // This is sort of funky. The corresponding functions in VarBase
190 // can't be const, since the versions in dynvar::Base call
191 // set_val(), which certainly isn't const. These versions
192 // can be const, however, since (const Variable) is a pointer
193 // to VarBase, not (const VarBase).
194
195 bool is_bool() const {return (*this)->is_bool();}
196 bool is_int() const {return (*this)->is_int();}
197 bool is_double() const {return (*this)->is_double();}
198 bool is_string() const {return (*this)->is_string();}
199 bool is_array() const {return array() != nullptr;}
200};
201
202class VARCONF_API VarArray : public VarBase, public VarList {
203public:
204 VarArray() = default;
205 VarArray(const VarArray& v) = default;
206 explicit VarArray(const int n, const Variable& v = Variable())
207 : VarBase(), VarList(n, v) {}
208 explicit VarArray(const VarList& v) : VarBase(), VarList(v) {}
209 ~VarArray() override;
210
211 friend std::ostream& operator<<(std::ostream& out, const VarArray& v);
212 friend bool operator ==(const VarBase& one, const VarArray& two) {return false;}
213 friend bool operator ==(const VarArray& one, const VarBase& two) {return false;}
214 friend bool operator ==(const VarArray& one, const VarArray& two);
215
216 explicit operator bool() const override;
217 explicit operator int() const override;
218 explicit operator double() const override;
219 explicit operator std::string() const override;
220
221 bool is_bool() override;
222 bool is_int() override;
223 bool is_double() override;
224 bool is_string() override;
225};
226
227} // namespace varconf
228
229#endif