Line data Source code
1 : /********************************************************************\
2 : * kvp-value.hpp -- Implements a key-value frame system *
3 : * Copyright (C) 2014 Aaron Laws *
4 : * *
5 : * This program is free software; you can redistribute it and/or *
6 : * modify it under the terms of the GNU General Public License as *
7 : * published by the Free Software Foundation; either version 2 of *
8 : * the License, or (at your option) any later version. *
9 : * *
10 : * This program is distributed in the hope that it will be useful, *
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 : * GNU General Public License for more details. *
14 : * *
15 : * You should have received a copy of the GNU General Public License*
16 : * along with this program; if not, contact: *
17 : * *
18 : * Free Software Foundation Voice: +1-617-542-5942 *
19 : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
20 : * Boston, MA 02110-1301, USA gnu@gnu.org *
21 : * *
22 : \********************************************************************/
23 :
24 : #ifndef GNC_KVP_VALUE_TYPE
25 : #define GNC_KVP_VALUE_TYPE
26 :
27 : #include <config.h>
28 : #include "qof.h"
29 :
30 : #include <cstdint>
31 : #include <boost/variant.hpp>
32 :
33 : //Must be a struct because it's exposed to C so that it can in turn be
34 : //translated to/from Scheme.
35 : /** @addtogroup KVP
36 : * @{
37 : */
38 :
39 : /** Implements KvpValue using boost::variant. Capable of holding the following
40 : * types:
41 : * * int64_t
42 : * * double
43 : * * gnc_numeric
44 : * * const char*
45 : * * GncGUID*
46 : * * Timepsec
47 : * * GList*
48 : * * KvpFrame*
49 : * * GDate
50 : */
51 :
52 : struct KvpValueImpl
53 : {
54 : public:
55 : enum Type
56 : {
57 : INVALID = -1,
58 : INT64 = 1, /**< QOF_TYPE_INT64 gint64 */
59 : DOUBLE, /**< QOF_TYPE_DOUBLE gdouble */
60 : NUMERIC, /**< QOF_TYPE_NUMERIC */
61 : STRING, /**< QOF_TYPE_STRING gchar* */
62 : GUID, /**< QOF_TYPE_GUID */
63 : TIME64, /**< QOF_TYPE_DATE */
64 : PLACEHOLDER_DONT_USE, /* Replaces KVP_TYPE_BINARY */
65 : GLIST, /**< no QOF equivalent. */
66 : FRAME, /**< no QOF equivalent. */
67 : GDATE, /**< no QOF equivalent. */
68 : };
69 :
70 : /**
71 : * Performs a deep copy
72 : */
73 : KvpValueImpl(KvpValueImpl const &) noexcept;
74 : KvpValueImpl& operator=(const KvpValueImpl&) noexcept;
75 :
76 : /**
77 : * Move. The old object's datastore is set to int64_t 0.
78 : */
79 : KvpValueImpl(KvpValueImpl && b) noexcept;
80 : KvpValueImpl& operator=(KvpValueImpl && b) noexcept;
81 :
82 : /** Create a KvpValue containing the passed in item. Note that for pointer
83 : * types const char*, KvpFrame*, GncGUID*, and GList* the KvpValue takes
84 : * ownership of the object and will delete/free it when the KvpValue is
85 : * destroyed. That means these objects must be allocated in the free store
86 : * or heap as follows:
87 : * * const char*: GLib string allocation, e.g. g_strdup()/
88 : * * KvpFrame*: operator new
89 : * * GncGUID*: guid_new() or guid_copy()
90 : * * GList*: Uses g_list_free(), so it's up to classes using this to empty
91 : the list before destroying the KvpValue.
92 : */
93 :
94 : template <typename T>
95 : KvpValueImpl(T) noexcept;
96 :
97 : /**
98 : * Performs a deep delete.
99 : *
100 : * The contents of this KvpValueImpl are also deleted.
101 : */
102 : ~KvpValueImpl() noexcept;
103 :
104 : /**
105 : * Adds another value to this KvpValueImpl.
106 : *
107 : * If this KvpValueImpl represents a collection (GList),
108 : * the new value is added to the collection and this
109 : * is returned.
110 : *
111 : * Otherwise, a new KvpValueImpl representing a collection
112 : * is created, this and the new value are added to it,
113 : * and it is returned.
114 : */
115 : KvpValueImpl * add (KvpValueImpl *) noexcept;
116 :
117 : KvpValueImpl::Type get_type() const noexcept;
118 :
119 : std::string to_string() const noexcept;
120 : std::string to_string(std::string const & prefix) const noexcept;
121 :
122 : template <typename T>
123 : T get() const noexcept;
124 : template <typename T>
125 : const T* get_ptr() const noexcept;
126 :
127 : template <typename T>
128 : void set(T) noexcept;
129 :
130 : friend int compare(const KvpValueImpl &, const KvpValueImpl &) noexcept;
131 :
132 : private:
133 : void duplicate(const KvpValueImpl&) noexcept;
134 : boost::variant<
135 : int64_t,
136 : double,
137 : gnc_numeric,
138 : const char*,
139 : GncGUID *,
140 : Time64,
141 : GList *,
142 : KvpFrame *,
143 : GDate> datastore;
144 : };
145 :
146 : int
147 : compare(const KvpValueImpl *, const KvpValue *) noexcept;
148 : /** @} Close Doxygen AddToGroup */
149 : template <typename T>
150 4037 : KvpValueImpl::KvpValueImpl(T newvalue) noexcept:
151 4037 : datastore(newvalue)
152 : {
153 4037 : }
154 :
155 : template <typename T> T
156 12105 : KvpValueImpl::get() const noexcept
157 : {
158 12105 : if (this->datastore.type() != boost::typeindex::type_id<T>()) return {};
159 12034 : return boost::get<T>(datastore);
160 : }
161 :
162 : template <typename T> const T*
163 23 : KvpValueImpl::get_ptr() const noexcept
164 : {
165 23 : if (this->datastore.type() != typeid(T)) return nullptr;
166 23 : return boost::get<T>(&datastore);
167 : }
168 :
169 : template <typename T> void
170 0 : KvpValueImpl::set(T val) noexcept
171 : {
172 0 : this->datastore = val;
173 0 : }
174 : /** @ingroup KVP
175 : @{ */
176 : /** @internal @{ */
177 : /** Convert a kvp_value into a GValue. Frames aren't converted.
178 : * @param kval: A KvpValue.
179 : * @param val: The GValue in which to store the converted value.
180 : */
181 : void gvalue_from_kvp_value (const KvpValue *kval, GValue* val);
182 :
183 : /** Convert a gvalue into a kvpvalue.
184 : * @param gval: A GValue of a type KvpValue can digest.
185 : * @return KvpValue created from the GValue's contents.
186 : */
187 : KvpValue* kvp_value_from_gvalue (const GValue *gval);
188 :
189 : /** @} Close Doxygen Internal */
190 : /** @} Close Doxygen Group */
191 :
192 : #endif
|