Skip to content

Commit

Permalink
More JSON updates. Basically code cleanup and redux.
Browse files Browse the repository at this point in the history
  • Loading branch information
staleyLANL committed Feb 1, 2024
1 parent aff80db commit 2e98e25
Show file tree
Hide file tree
Showing 13 changed files with 389 additions and 159 deletions.
40 changes: 32 additions & 8 deletions simple-json/src/json-array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,46 @@

class array : public std::vector<value> {
public:

// ------------------------
// Construction
// ------------------------

using vector::vector;
using vector::operator=;
array(const vector &from) : vector(from) { }
array(vector &&from) : vector(std::move(from)) { }
array &operator=(const vector &from)
{ static_cast<vector &>(*this) = from; return *this; }
array &operator=(vector &&from)
{ static_cast<vector &>(*this) = std::move(from); return *this; }

// 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 std::vector<T> &from) :
vector(from.begin(), from.end())
{ }

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

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

// ------------------------
// Assignment
// ------------------------

template<class T, class = std::enable_if_t<std::is_assignable_v<vector,T>>>
array &operator=(const T &from)
{ vector::operator=(from); return *this; }

template<class T, class = std::enable_if_t<std::is_assignable_v<vector,T>>>
array &operator=(T &&from)
{ vector::operator=(std::move(from)); return *this; }

// ------------------------
// read, write
// ------------------------

template<class T = void, class U = void>
auto read(std::istream &is, const int = as_literal::none)
-> decltype(number().read<T,U>(is,0)); // SFINAE: need number::read<T,U>

void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
};
26 changes: 21 additions & 5 deletions simple-json/src/json-boolean.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,35 @@ class boolean {

public:

// constructor: default
boolean() : b(false) { }
// ------------------------
// Construction
// ------------------------

// constructor: from bool
// default
boolean() :
b(false)
{ }

// from bool
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
// ------------------------

// convert: to bool
// to bool
operator const bool &() const { return b; }
operator bool &() { return b; }

// ------------------------
// read, write
// ------------------------

template<class T = void, class U = void>
std::string read(std::istream &, const int = as_literal::none);

void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
};
16 changes: 12 additions & 4 deletions simple-json/src/json-chars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,14 @@ class chars {

public:

// constructor: default
// ------------------------
// Construction
// ------------------------

// default
chars() { }

// constructor: from float, double, or long double
// from float, double, or long double
template<
class T,
class = std::enable_if_t<
Expand All @@ -39,11 +43,15 @@ class chars {
str(buf, std::to_chars(buf,buf+SIZE,from,format).ptr - buf)
{ }

// convert: to std::string
// ------------------------
// Conversion
// ------------------------

// to std::string
operator const std::string &() const { return str; }
operator std::string &() { return str; }

// convert: to literal
// to literal
operator literal() const
{
return literal(str);
Expand Down
25 changes: 14 additions & 11 deletions simple-json/src/json-detail-pre.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace detail {
// -----------------------------------------------------------------------------

// inVariant
// count == number of times T is exactly the same as a type in the std::variant
// count == number of times T is exactly the same as a type in a std::variant
template<class, class>
struct inVariant { };

Expand All @@ -17,7 +17,7 @@ struct inVariant<T, std::variant<As...>>
};

// toVariant
// count == number of times T is convertible to a type in the std::variant
// count == number of times T is convertible to a type in a std::variant
template<class, class>
struct toVariant { };

Expand All @@ -36,15 +36,18 @@ struct toVariant<T, std::variant<A,As...>>
};

// For brevity
template<class T, class VARIANT> inline constexpr bool
invar = inVariant<T,VARIANT>::count == 1;
template<class T, class VARIANT> inline constexpr bool
tovar = toVariant<T,VARIANT>::count == 1;

template<class T> inline constexpr bool isintegral =
std::is_integral_v<std::decay_t<T>>;
template<class T> inline constexpr bool isfloating =
std::is_floating_point_v<std::decay_t<T>>;
// invar
// tovar
// isintegral
// isfloating
template<class T, class VARIANT>
inline constexpr bool invar = inVariant<T,VARIANT>::count == 1;
template<class T, class VARIANT>
inline constexpr bool tovar = toVariant<T,VARIANT>::count == 1;
template<class T>
inline constexpr bool isintegral = std::is_integral_v<std::decay_t<T>>;
template<class T>
inline constexpr bool isfloating = std::is_floating_point_v<std::decay_t<T>>;

// variant2tuple
template<class>
Expand Down
4 changes: 3 additions & 1 deletion simple-json/src/json-diagnostic-detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ inline std::string color(const int r, const int g, const int b)
// diagnostic
inline void diagnostic(
std::istream &is,
const std::string &message, const std::string &label
const std::string &message,
const std::string &label
) {
static const std::string reset = "\033[0m"; // all colors/decorations off
const std::string spaces(indent,' ');
Expand Down Expand Up @@ -62,6 +63,7 @@ inline void diagnostic(
for (const char &ch : message)
std::cout << ch << (ch == '\n' ? spaces : "");
std::cout << reset << std::endl;

if (quit)
error("Unable to recover. istream.seekg() failed after attempt\n"
"to determine line number for previous diagnostic.");
Expand Down
28 changes: 21 additions & 7 deletions simple-json/src/json-literal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,36 @@ class literal {

public:

// constructor: default
// ------------------------
// Construction
// ------------------------

// default
literal() { }

// constructor: from std::string
// 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 literal(const std::string &from) :
str(from)
{ }

// ------------------------
// Conversion
// ------------------------

// to std::string
operator const std::string &() const { return str; }
operator std::string &() { return str; }

// ------------------------
// read, write
// ------------------------

template<class T = void, class U = void>
std::string read(std::istream &, const int = as_literal::none);
void write(std::ostream & = std::cout, const int = 0, const int = -1) const;

// convert: to std::string
operator const std::string &() const { return str; }
operator std::string &() { return str; }
void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
};
18 changes: 15 additions & 3 deletions simple-json/src/json-null.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,33 @@
class null {
public:

// constructor: default
// ------------------------
// Construction
// ------------------------

// default
null() { }

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

// convert: to std::nullptr_t
// ------------------------
// Conversion
// ------------------------

// to std::nullptr_t
operator const std::nullptr_t &() const
{ static const std::nullptr_t ret = nullptr; return ret; }
operator std::nullptr_t &()
{ static std::nullptr_t ret = nullptr; return ret; }

// ------------------------
// read, write
// ------------------------

template<class T = void, class U = void>
std::string read(std::istream &, const int = as_literal::none);

void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
};
88 changes: 67 additions & 21 deletions simple-json/src/json-number.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,64 @@ class number
#include "json-number-helper.hpp"

public:
using variant::operator=;
number(const variant &from) : variant(from) { }
number(variant &&from) : variant(std::move(from)) { }
number &operator=(const variant &from)
{ static_cast<variant &>(*this) = from; return *this; }
number &operator=(variant &&from)
{ static_cast<variant &>(*this) = std::move(from); return *this; }

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

// constructor: from T in the variant

// ------------------------
// 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) { }
number(const T &from) :
variant(from)
{ }

// read, write
template<
class T = void, class U = void,
class = std::enable_if_t<types<T,U>::compatible>
>
std::string read(std::istream &, const int = as_literal::none);
void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
// ------------------------
// Assignment
// ------------------------

template<class T, class = std::enable_if_t<std::is_assignable_v<variant,T>>>
number &operator=(const T &from)
{ variant::operator=(from); return *this; }

template<class T, class = std::enable_if_t<std::is_assignable_v<variant,T>>>
number &operator=(T &&from)
{ variant::operator=(std::move(from)); return *this; }

// has
// ------------------------
// Conversion
// ------------------------

// to T
template<class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
operator T() const
{
return std::visit(
[](const auto &alt)
{
return T(alt);
},
static_cast<const variant &>(*this)
);
}

// ------------------------
// Other
// ------------------------

// has<T>
template<class T, class = std::enable_if_t<detail::invar<T,variant>>>
bool has() const { return std::holds_alternative<T>(*this); }

Expand All @@ -59,4 +93,16 @@ class number
const T &get() const { return std::get<T>(*this); }
template<class T, class = std::enable_if_t<detail::invar<T,variant>>>
T &get() { return std::get<T>(*this); }

// ------------------------
// read, write
// ------------------------

template<
class T = void, class U = void,
class = std::enable_if_t<types<T,U>::compatible>
>
std::string read(std::istream &, const int = as_literal::none);

void write(std::ostream & = std::cout, const int = 0, const int = -1) const;
};
Loading

0 comments on commit 2e98e25

Please sign in to comment.