24 #include "kvp-value.hpp" 25 #include "kvp-frame.hpp" 32 using boost::typeindex::type_id;
40 KvpValueImpl::operator=(
KvpValueImpl const & other) noexcept
48 datastore = b.datastore;
49 b.datastore = INT64_C(0);
55 std::swap (datastore, b.datastore);
63 if (this->datastore.type() == type_id<GList*>())
65 GList * list = boost::get<GList*>(datastore);
66 datastore = g_list_append (list, val);
70 GList *list =
nullptr;
72 list = g_list_append (list,
this);
73 list = g_list_append (list, val);
78 KvpValueImpl::get_type() const noexcept
80 if (datastore.type() == type_id<int64_t>())
81 return KvpValue::Type::INT64;
82 else if (datastore.type() == type_id<double>())
83 return KvpValue::Type::DOUBLE;
84 else if (datastore.type() == type_id<gnc_numeric>())
85 return KvpValue::Type::NUMERIC;
86 else if (datastore.type() == type_id<const gchar *>())
87 return KvpValue::Type::STRING;
88 else if (datastore.type() == type_id<GncGUID *>())
89 return KvpValue::Type::GUID;
90 else if (datastore.type() == type_id<Time64>())
91 return KvpValue::Type::TIME64;
92 else if (datastore.type() == type_id<GList *>())
93 return KvpValue::Type::GLIST;
94 else if (datastore.type() == type_id<KvpFrameImpl *>())
95 return KvpValue::Type::FRAME;
96 else if (datastore.type() == type_id<GDate>())
97 return KvpValue::Type::GDATE;
99 return KvpValue::Type::INVALID;
104 std::ostringstream & output;
108 void operator()(int64_t val)
110 output << val <<
" (64-bit int)";
113 void operator()(KvpFrame* val)
115 output << val->to_string();
118 void operator()(GDate val)
120 output << std::setw(4) << g_date_get_year(&val) <<
'-';
121 output << std::setw(2) << g_date_get_month(&val) <<
'-';
122 output << std::setw(2) << g_date_get_day(&val);
123 output <<
" (gdate)";
126 void operator()(GList * val)
128 output <<
"KVP_VALUE_GLIST(";
131 for (;val; val = val->next)
133 auto realvalue =
static_cast<const KvpValue *
>(val->data);
134 output <<
' ' << realvalue->to_string() <<
',';
140 void operator()(
Time64 val)
144 output << tmp1 <<
" (time64)";
147 void operator()(gnc_numeric val)
159 output <<
" (gnc_numeric)";
177 void operator()(
const char * val)
179 output << val <<
" (char *)";
182 void operator()(
double val)
184 output << val <<
" (double)";
189 KvpValueImpl::to_string(std::string
const & prefix)
const noexcept
191 if (this->datastore.type() == type_id<KvpFrame*>())
192 return this->get<KvpFrame*>()->to_string(prefix);
193 std::ostringstream ret;
195 boost::apply_visitor(visitor, datastore);
197 return prefix + ret.str();
201 KvpValueImpl::to_string() const noexcept
203 return to_string(
"");
207 kvp_glist_compare(
const GList * list1,
const GList * list2)
212 if (list1 == list2)
return 0;
215 if (!list1 && list2)
return -1;
216 if (list1 && !list2)
return 1;
222 KvpValue *v1 = (KvpValue *) lp1->data;
223 KvpValue *v2 = (KvpValue *) lp2->data;
224 gint vcmp = compare(v1, v2);
225 if (vcmp != 0)
return vcmp;
229 if (!lp1 && lp2)
return -1;
230 if (!lp2 && lp1)
return 1;
235 kvp_glist_copy(
const GList * list)
237 GList * retval = NULL;
240 if (!list)
return retval;
244 retval = g_list_copy((GList *) list);
247 for (lptr = retval; lptr; lptr = lptr->next)
249 lptr->data =
new KvpValue(*static_cast<KvpValue *>(lptr->data));
257 template <
typename T,
typename U>
258 int operator()( T& one, U& two)
const 260 throw std::invalid_argument{
"You may not compare objects of different type."};
263 template <
typename T>
264 int operator()( T & one, T & two)
const 274 template <>
int compare_visitor::operator()(
const char *
const & one,
const char *
const & two)
const 276 return strcmp(one, two);
278 template <>
int compare_visitor::operator()(gnc_numeric
const & one, gnc_numeric
const & two)
const 282 template <>
int compare_visitor::operator()(
GncGUID *
const & one,
GncGUID *
const & two)
const 284 return guid_compare(one, two);
286 template <>
int compare_visitor::operator()(
Time64 const & one,
Time64 const & two)
const 288 return one.t < two.t ? -1 : one.t > two.t ? 1 : 0;
290 template <>
int compare_visitor::operator()(GDate
const & one, GDate
const & two)
const 292 return g_date_compare(&one,&two);
294 template <>
int compare_visitor::operator()(GList *
const & one, GList *
const & two)
const 296 return kvp_glist_compare(one, two);
298 template <>
int compare_visitor::operator()(KvpFrame *
const & one, KvpFrame *
const & two)
const 300 return compare(one, two);
302 template <>
int compare_visitor::operator()(
double const & one,
double const & two)
const 304 if (std::isnan(one) && std::isnan(two))
306 if (one < two)
return -1;
307 if (two < one)
return 1;
313 auto type1 = one.get_type();
314 auto type2 = two.get_type();
317 return type1 < type2 ? -1 : 1;
320 return boost::apply_visitor(comparer, one.datastore, two.datastore);
326 if (one == two)
return 0;
327 if (one && !two)
return 1;
328 if (!one && two)
return -1;
330 return compare(*one, *two);
335 template <
typename T>
void 340 destroy_value(
void* item)
342 delete static_cast<KvpValue*
>(item);
346 delete_visitor::operator()(GList * & value)
348 g_list_free_full(value, destroy_value);
351 delete_visitor::operator()(
const gchar * & value)
353 g_free(const_cast<gchar *> (value));
356 delete_visitor::operator()(
GncGUID * & value)
361 delete_visitor::operator()(KvpFrame * & value)
369 boost::apply_visitor(d, datastore);
373 KvpValueImpl::duplicate(
const KvpValueImpl& other) noexcept
375 if (other.datastore.type() == type_id<const gchar *>())
376 this->datastore =
const_cast<const gchar *
>(g_strdup(other.get<
const gchar *>()));
377 else if (other.datastore.type() == type_id<GncGUID*>())
379 else if (other.datastore.type() == type_id<GList*>())
380 this->datastore = kvp_glist_copy(other.get<GList *>());
381 else if (other.datastore.type() == type_id<KvpFrame*>())
382 this->datastore =
new KvpFrame(*other.get<KvpFrame *>());
384 this->datastore = other.datastore;
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
gchar * gnc_numeric_to_string(gnc_numeric n)
Convert to string.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
KvpValueImpl * add(KvpValueImpl *) noexcept
Adds another value to this KvpValueImpl.
Implements KvpValue using boost::variant.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
KvpValueImpl(KvpValueImpl const &) noexcept
Performs a deep copy.
~KvpValueImpl() noexcept
Performs a deep delete.
The type used to store guids in C.
char * gnc_time64_to_iso8601_buff(time64 time, char *buff)
The gnc_time64_to_iso8601_buff() routine takes the input UTC time64 value and prints it as an ISO-860...