Skip to content

Commit

Permalink
JSON updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
staleyLANL committed Oct 1, 2024
1 parent 89c6036 commit 8ac1aef
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 124 deletions.
2 changes: 2 additions & 0 deletions simple-json/src/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

*.hh
13 changes: 5 additions & 8 deletions simple-json/src/json-array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@ class array : public std::vector<value> {
// Construction
// ------------------------

// inherited
using vector::vector;

// from instance of base class
array(const vector &from) : vector(from) { }
array(vector &&from) : vector(std::move(from)) { }

// constructor: from std::vector<T convertible to value>
template<class T, class = std::enable_if_t<std::is_convertible_v<T,value>>>
array(const std::vector<T> &from) :
vector(from.begin(), from.end())
{ }

array(const vector &from) :
vector(from)
{ }

array(vector &&from) :
vector(std::move(from))
{ }

// ------------------------
// Assignment
// ------------------------
Expand Down
10 changes: 3 additions & 7 deletions simple-json/src/json-boolean.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@ class boolean {
// ------------------------

// default
boolean() :
b(false)
{ }
boolean() : b(false) { }

// from bool
// from bool (exactly)
template<class T, class = std::enable_if_t<std::is_same_v<T,bool>>>
boolean(const T &from) :
b(from)
{ }
boolean(const T &from) : b(from) { }

// ------------------------
// Conversion
Expand Down
11 changes: 4 additions & 7 deletions simple-json/src/json-literal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,10 @@ class literal {
literal() { }

// from std::string
// Explicit, so that std::string prefers string's constructor, not literal's.
// We want literal to be something we get only by specifically asking for it.
// Note also that this constructor's being explicit lets us dispense with the
// enable_if business that we spoke of above class null's definition.
explicit literal(const std::string &from) :
str(from)
{ }
// Explicit, so that std::string prefers json::string's constructor, not
// json::literal's. We want json::literal to be something we get only by
// specifically asking for it.
explicit literal(const std::string &from) : str(from) { }

// ------------------------
// Assignment
Expand Down
2 changes: 1 addition & 1 deletion simple-json/src/json-null.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class null {
// default
null() { }

// from std::nullptr_t
// from std::nullptr_t (exactly)
template<class T, class = std::enable_if_t<std::is_same_v<T,std::nullptr_t>>>
null(const T &) { }

Expand Down
31 changes: 12 additions & 19 deletions simple-json/src/json-number.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,15 @@ class number
// Construction
// ------------------------

// default
number() :
variant(0)
{ }

// from variant
number(const variant &from) :
variant(from)
{ }
number(variant &&from) :
variant(std::move(from))
{ }

// from T in the variant
template<class T, class = std::enable_if_t<detail::invar<T,variant>>>
number(const T &from) :
variant(from)
{ }
// inherited
using variant::variant;

// default (override inherited because we want to select int)
number() : variant(0) { }

// from instance of base class
number(const variant &from) : variant(from) { }
number(variant &&from) : variant(std::move(from)) { }

// ------------------------
// Assignment
Expand All @@ -68,7 +59,9 @@ class number
// Conversion
// ------------------------

// to T
// to arithmetic T
// Returns by value, so that we need not assume that the underlying
// variant holds exactly a T. Also, then, we need only a const version.
template<class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
operator T() const
{
Expand Down
9 changes: 2 additions & 7 deletions simple-json/src/json-object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ class object : public std::vector<pair> {
// Construction
// ------------------------

// inherited
using vector::vector;

// from instance of base class
object(const vector &from) : vector(from) { }
object(vector &&from) : vector(std::move(from)) { }

Expand Down Expand Up @@ -42,13 +44,6 @@ class object : public std::vector<pair> {
// Other
// ------------------------

/*
// items
// Returns the std::vector base.
const vector &items() const { return *this; }
vector &items() { return *this; }
*/

// has key
bool has(const string &key) const;

Expand Down
44 changes: 8 additions & 36 deletions simple-json/src/json-string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,16 @@ class string : public std::string {
// Construction
// ------------------------

// default
string() { }
// inherited
using std::string::string;

// from std::string
// from const char *
// from char *
// from char
// Remark. For the "from char" case, using str{from} below, not str(from),
// allows std::string's constructor from initializer_list<char> to be used.
template<
class T,
class = std::enable_if_t<
std::is_same_v<T,std::string> ||
std::is_same_v<T,const char*> ||
std::is_same_v<T, char*> ||
std::is_same_v<T, char >
>
>
string(const T &from) :
std::string{from}
{ }

string(const std::string &from) :
std::string(from)
{ }
// from instance of base class
string(const std::string &from) : std::string(from) { }
string(std::string &&from) : std::string(std::move(from)) { }

string(std::string &&from) :
std::string(std::move(from))
{ }

// from char[N]
template<
class T, size_t N,
class = std::enable_if_t<std::is_same_v<T,char>>
>
string(const T (&from)[N]) :
std::string(from)
{ }
// from char (exactly)
template<class T, class = std::enable_if_t<std::is_same_v<T,char>>>
string(const T &from) : std::string{from} { }

// ------------------------
// Assignment
Expand Down
5 changes: 1 addition & 4 deletions simple-json/src/json-value-get.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
template<
class T,
class = std::enable_if_t<
std::is_same_v<T,std::string> ||
detail::invar<T,variant> ||
detail::invar<T,number::variant>
>
>
const T &get() const
{
if constexpr (std::is_same_v<T,std::string>)
return get<string>();
else if constexpr (detail::invar<T,variant>)
if constexpr (detail::invar<T,variant>)
return std::get<T>(*this);
else
return get<number>().get<T>();
Expand Down
2 changes: 1 addition & 1 deletion simple-json/src/json-value-is.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ bool is_number(const bool allowLiteral = true) const
const number &num = get<number>();

// Does the number actually hold a T?
if (std::holds_alternative<T>(number::variant(num)))
if (num.has<T>())
return true;

// The number has something other than a T. We'll say that the
Expand Down
72 changes: 38 additions & 34 deletions simple-json/src/json-value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,22 @@ class value
// Construction
// ------------------------

// inherited
using variant::variant;

// default
// default (override inherited because we want to select object)
value() : variant(object()) { }

// from variant
// from instance of base class
value(const variant &from) : variant(from) { }
value(variant &&from) : variant(std::move(from)) { }

// from initializer_list
// from std::nullptr_t
// from bool
// from std::initializer_list<value> ==> json::array
// from std::initializer_list<pair> ==> json::object
value(const std::nullptr_t &from) : variant(json::null(from)) { }
value(const bool &from) : variant(json::boolean(from)) { }
value(const std::initializer_list<value> &from) : variant(array(from)) { }
value(const std::initializer_list<pair> &from) : variant(object(from)) { }

Expand All @@ -51,36 +57,41 @@ class value
// Conversion
// ------------------------

// to T; arithmetic
template<
class T,
class = std::enable_if_t<std::is_arithmetic_v<T>>
>
template<class T>
using converts = std::enable_if_t<
detail::invar<T,value::variant> ||
std::is_same_v<T,std::nullptr_t> ||
std::is_same_v<T,std::string>
>;

// to arithmetic T
// Assumes json::number, and forwards to its conversion to arithmetic T.
// Returns by value; so, const only.
template<class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
operator T() const
{
return T(get<number>());
}

// to T; std::string, or in value's variant; const
template<
class T,
class = std::enable_if_t<
std::is_same_v<T,std::string> || detail::invar<T,variant>>
>
// to specific Ts; const
template<class T, class = converts<T>>
operator const T &() const
{
return get<T>();
if constexpr (detail::invar<T,value::variant>)
return get<T>();
else if constexpr (std::is_same_v<T,std::nullptr_t>)
return get<null>();
else if (has<json::literal>())
return get<json::literal>();
else
return get<json::string>();
}

// to T; std::string, or in value's variant; non-const
template<
class T,
class = std::enable_if_t<
std::is_same_v<T,std::string> || detail::invar<T,variant>>
>
// to specific Ts; non-const
template<class T, class = converts<T>>
operator T &()
{
return get<T>();
return const_cast<T &>((const T &)(std::as_const(*this)));
}

// ------------------------
Expand All @@ -91,7 +102,8 @@ class value
template<
class T,
class = std::enable_if_t<
detail::isintegral<T> || std::is_constructible_v<string,T>>
detail::isintegral<T> || std::is_constructible_v<string,T>
>
>
const value &operator[](const T &key) const
{
Expand All @@ -105,7 +117,8 @@ class value
template<
class T,
class = std::enable_if_t<
detail::isintegral<T> || std::is_constructible_v<string,T>>
detail::isintegral<T> || std::is_constructible_v<string,T>
>
>
value &operator[](const T &key)
{
Expand All @@ -120,26 +133,17 @@ class value
const std::vector<pair> &items() const { return get<object>(); }
std::vector<pair> &items() { return get<object>(); }

/*
// items
const std::vector<pair> &items() const { return get<object>().items(); }
std::vector<pair> &items() { return get<object>().items(); }
*/

// has alternative
template<
class T,
class = std::enable_if_t<
std::is_same_v<T,std::string> ||
detail::invar<T,variant> ||
detail::invar<T,number::variant>
>
>
bool has() const
{
if constexpr (std::is_same_v<T,std::string>)
return has<string>(); // <== json::string, not std::string
else if constexpr (detail::invar<T,variant>)
if constexpr (detail::invar<T,variant>)
return std::holds_alternative<T>(*this);
else
return has<number>() && get<number>().has<T>();
Expand Down

0 comments on commit 8ac1aef

Please sign in to comment.