Parsnip
parsing library
Data Structures | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Friends
Parsnip::Data Class Reference

Generic data type. More...

#include <parsnip.h>

Data Structures

union  data_t
 
struct  dictionary_t
 
struct  iterator
 An iterator used to walk items in Data's lists. More...
 
struct  list_t
 

Public Types

enum class  Type {
  Null , Dictionary , List , String ,
  FlexibleString , Integer , Real , Boolean
}
 Types that may be stored in the data. More...
 
using StringType = std::string
 
using ListType = std::vector< Data >
 
using size_type = ListType::size_type
 

Public Member Functions

 Data (std::nullptr_t null=nullptr)
 Default constructor.
 
 Data (const char *value, bool type_certainty=true)
 String constructor. More...
 
 Data (const std::string &value, bool type_certainty=true)
 String constructor, accepting C++ string.
 
template<typename T , typename = typename std::enable_if<!std::is_same<T, bool>::value && std::is_integral<T>::value, int>::type>
 Data (T value) noexcept
 Integer constructor.
 
 Data (double value) noexcept
 Floating point constructor.
 
 Data (bool value) noexcept
 Boolean constructor.
 
template<typename... T>
 Data (dictionary_t, T... params)
 Dictionary constructor. More...
 
template<typename... T>
 Data (list_t, T... params)
 List constructor. More...
 
 Data (Data &&from) noexcept
 Move construction.
 
Dataoperator= (Data &&from) noexcept
 Move assignment.
 
 Data (const Data &from)
 Copy constructor.
 
Dataoperator= (const Data &from)
 Copy assignment.
 
bool operator== (const Data &compare) const
 Compare two structures. More...
 
bool operator!= (const Data &compare) const
 
const DatamakeFlexible () const
 IF a data item is a string, change it to a flexible string. More...
 
bool isNull (void) const noexcept
 Check if data contains a value. More...
 
const StringType & asString () const
 Retrieve string value. More...
 
long asLong (int base=0) const
 Return value of data as a long integer. More...
 
int asInteger (int base=0) const
 Return value of data as an integer. More...
 
double asDouble () const
 Return value of data as a double. If the data is a string, parse it as a float.
 
bool asBoolean () const
 Return value of data as a boolean. If the data is a string, translate "true" and "false".
 
ListType asList () const
 Return data as a list. More...
 
template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, std::string>::value>::type>
const std::string & as () const
 Extract data as a string (templated version). More...
 
template<typename DataType , typename = typename std::enable_if<!std::is_same<DataType, bool>::value && std::is_integral<DataType>::value>::type>
DataType as (int base=0) const
 Extract data as an integer type, except boolean. More...
 
template<typename DataType , typename = typename std::enable_if<std::is_floating_point<DataType>::value>::type>
DataType as () const
 Extract data as a floating point type. More...
 
template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, bool>::value>::type>
bool as () const
 Extract data as a boolean. More...
 
template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, Data>::value>::type>
const Dataas () const
 Retrieve data as the object itself. More...
 
template<typename Container , typename = typename std::enable_if<std::is_class<Container>::value && !std::is_same<Container, Data>::value && !std::is_same<Container, std::string>::value>::type>
Container as (std::nullptr_t null=nullptr) const
 Return contents of a list as a specific datatype. More...
 
template<typename Datatype >
Datatype getOr (const std::string &name, const Datatype &defvalue) const
 Extract a value if a member exists, otherwise use a default. More...
 
StringType getOr (const std::string &name, const char *defvalue) const
 Specialization of 'getOr' that accepts a const char * default; otherwise, overload resolution chooses implicit instantiation of a Data and uses that as a default rather than implicitly instantiating the string type.
 
Data getOr (const std::string &name, const Data &defvalue) const
 Specialization of getOr for Data. More...
 
template<typename Datatype >
std::vector< Datatype > toList () const
 Return a list or a single item in a container. More...
 
const Dataoperator[] (const std::string &word) const
 Dictionary member accessor. More...
 
Dataoperator[] (const std::string &word)
 Dictionary member accessor. More...
 
bool contains (const std::string &word) const
 Check if a key exists in a dictionary. More...
 
void remove (const std::string &word)
 Remove key from dictionary.
 
const Dataat (const std::string &word) const
 
template<typename DataType , typename = typename std::enable_if<std::is_trivial<DataType>::value>::type>
void foreach (std::function< void(const std::string &, DataType)> func) const
 Iterate over all dictionary members, calling a function with each key and value. More...
 
template<typename DataType >
void foreach (std::function< void(const std::string &, const DataType &)> func) const
 Specialization of dictionary iterator for strings and Data.
 
const Dataoperator[] (size_type index) const
 List member accessor. More...
 
Dataoperator[] (size_type index)
 List member accessor. More...
 
void remove (size_type index)
 Remove entry from position in list.
 
void push_back (const Data &value)
 List back-inserter.
 
void push_back (Data &&value)
 List back-inserter.
 
size_type size () const
 Retrieve number of entries in a list. More...
 
bool empty () const
 Empty check. More...
 
template<typename DataType , typename = typename std::enable_if<std::is_trivial<Type>::value>::type>
void foreach (std::function< void(const DataType)> func) const
 Iterate over all list members, calling a function with each value. More...
 
template<typename DataType >
void foreach (std::function< void(const DataType &)> func) const
 Specialization of list iterator for strings and Data.
 
Data::iterator begin () const
 Retrieve forward iterator. More...
 
Data::iterator end () const
 Retrieve end iterator. More...
 
std::string toJson (int indent=NoIndent) const
 Return serial data encoded using JSON. More...
 
std::ostream & toJson (std::ostream &target, int indent=NoIndent, bool suppress=false) const
 Write serial data encoded using JSON. More...
 
std::ostream & dumpJson (const std::string &intro, std::ostream &target=std::clog) const
 

Static Public Member Functions

static const char * type_name (Type ty)
 Return the name corresponding to a type. More...
 
template<typename T = Data>
static Data make_dictionary (std::initializer_list< std::pair< const char *, const T >> initial_data)
 Dictionary factory. More...
 
template<typename... T>
static Data make_list (T &&... params)
 List factory. More...
 

Static Public Attributes

static const struct Parsnip::Data::dictionary_t Dictionary
 Dictionary flag type/value.
 
static const struct Parsnip::Data::list_t List
 List flag type/value.
 
static constexpr bool Flexible {false}
 Flag to make strings flexible.
 
static constexpr int NoIndent {-32767}
 Prevent indentation.
 

Protected Types

using DictionaryType = std::unordered_map< std::string, Data >
 

Protected Member Functions

void release ()
 Release any stored data and restore to an "empty" state.
 

Protected Attributes

Type datatype = Type::Null
 Type presently stored in object.
 
union Parsnip::Data::data_t data
 

Friends

class IncorrectDataType
 
class SchemaBase
 
class DictionarySchema
 
class ConjunctionSchema
 

Detailed Description

Generic data type.

A datatype that can hold strings, numbers, booleans, lists, or dictionaries.

Member Enumeration Documentation

◆ Type

enum Parsnip::Data::Type
strong

Types that may be stored in the data.

Enumerator
Null 

Nothing is present.

List 

Dictionary keyed by string.

String 

The value is string, even if the string contains a number.

FlexibleString 

The value is a string, but may convert to a number if the value is numeric.

Integer 

Value is an integer but may also be accessed as a real.

Constructor & Destructor Documentation

◆ Data() [1/3]

Parsnip::Data::Data ( const char *  value,
bool  type_certainty = true 
)
inline

String constructor.

Parameters
valueThe string value to assign.
type_certaintyTrue if known to be string, false if it may be a number or boolean in string form.

◆ Data() [2/3]

template<typename... T>
Parsnip::Data::Data ( dictionary_t  ,
T...  params 
)
inline

Dictionary constructor.

Use Dictionary flag variable as first parameter. Subsequent parameters are name, value ... pairs (function must have an odd number of arguments).

◆ Data() [3/3]

template<typename... T>
Parsnip::Data::Data ( list_t  ,
T...  params 
)
inline

List constructor.

Use List flag variable as first parameter. Subsequent parameters are inserted in order as list members.

Member Function Documentation

◆ as() [1/6]

template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, std::string>::value>::type>
const std::string& Parsnip::Data::as ( ) const
inline

Extract data as a string (templated version).

Exceptions
IncorrectDataTypeif value is not a string.

◆ as() [2/6]

template<typename DataType , typename = typename std::enable_if<std::is_floating_point<DataType>::value>::type>
DataType Parsnip::Data::as ( ) const
inline

Extract data as a floating point type.

Template Parameters
DataTypethe desired return type.
Exceptions
DataRangeErrorif value will not fit DataType.
IncorrectDataTypeif value is not a number.

◆ as() [3/6]

template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, bool>::value>::type>
bool Parsnip::Data::as ( ) const
inline

Extract data as a boolean.

Exceptions
IncorrectDataTypeif value is not true or false.

◆ as() [4/6]

template<typename DataType , typename = typename std::enable_if<std::is_same<DataType, Data>::value>::type>
const Data& Parsnip::Data::as ( ) const
inline

Retrieve data as the object itself.

Seems stupid on the surface, but useful for templates.

◆ as() [5/6]

template<typename DataType , typename = typename std::enable_if<!std::is_same<DataType, bool>::value && std::is_integral<DataType>::value>::type>
DataType Parsnip::Data::as ( int  base = 0) const
inline

Extract data as an integer type, except boolean.

Template Parameters
DataTypethe desired return type.
Exceptions
DataRangeErrorif value will not fit in DataType.
IncorrectDataTypeif value is not an integer.

◆ as() [6/6]

template<typename Container , typename = typename std::enable_if<std::is_class<Container>::value && !std::is_same<Container, Data>::value && !std::is_same<Container, std::string>::value>::type>
Container Parsnip::Data::as ( std::nullptr_t  null = nullptr) const
inline

Return contents of a list as a specific datatype.

Template Parameters
ContainerA standard (-like) container, such as std::vector <std::string>, std::list <int>, or even std::vector<std::vector<long>> to extract a contents of a 2-dimensional array. Member typedef Container::value_type determines the inner type.
Exceptions
IncorrectDataTypeif the item is not a list, or any of the list's members are not the expected type.

◆ asInteger()

int Parsnip::Data::asInteger ( int  base = 0) const

Return value of data as an integer.

See also
asLong().
Parameters
baseThe base for interpreting strings. Default is 10.
Returns
The integer.
Exceptions
DataRangeErrorif the value is out of representable range.

◆ asList()

Data::ListType Parsnip::Data::asList ( ) const

Return data as a list.

  • Null data is returned as an empty list.
  • Lists return a copy of their elements.
  • Individual elements are wrapped in a 1-element list.
    Exceptions
    IncorrectDataTypefor dictionaries.

◆ asLong()

long Parsnip::Data::asLong ( int  base = 0) const

Return value of data as a long integer.

If the data is a string, parse it as an integer.

Parameters
baseThe base for interpreting strings. Default is 10.
Returns
The long integer.
Exceptions
DataRangeErrorif the value is out of representable range.

◆ asString()

const Data::StringType & Parsnip::Data::asString ( ) const

Retrieve string value.

Returns
String value.
Exceptions
IncorrectDataTypeif value is not a string.

◆ begin()

Data::iterator Parsnip::Data::begin ( ) const
inline

Retrieve forward iterator.

Returns
Forward iterator positioned at first element.
Exceptions
IncorrectDataTypeif not a list.

◆ contains()

bool Parsnip::Data::contains ( const std::string &  key) const

Check if a key exists in a dictionary.

Parameters
keyThe key to check.
Returns
True if present in dictionary, false otherwise.

◆ empty()

bool Parsnip::Data::empty ( ) const
inline

Empty check.

Use isNull to check specifically for that condition.

Returns
True for null type, or lists or dictionaries that are empty.

◆ end()

Data::iterator Parsnip::Data::end ( ) const
inline

Retrieve end iterator.

Returns
Forward iterator positioned after last element.
Exceptions
IncorrectDataTypeif not a list.

◆ foreach() [1/2]

template<typename DataType , typename = typename std::enable_if<std::is_trivial<Type>::value>::type>
void Parsnip::Data::foreach ( std::function< void(const DataType)>  func) const
inline

Iterate over all list members, calling a function with each value.

This implementation covers simple types.

Template Parameters
DataTypeThe datatype expected to be in the dictionary.
Parameters
funcThe function to invoke with each member.
Exceptions
IncorrectDataTypeif the list contains values of inapplicable type. This occurs when encountered; some invokations may happen before throwing.

◆ foreach() [2/2]

template<typename DataType , typename = typename std::enable_if<std::is_trivial<DataType>::value>::type>
void Parsnip::Data::foreach ( std::function< void(const std::string &, DataType)>  func) const
inline

Iterate over all dictionary members, calling a function with each key and value.

This implementation covers simple types.

Template Parameters
DataTypeThe datatype expected to be in the dictionary.
Parameters
funcThe function to invoke with each member.
Exceptions
IncorrectDataTypeif the dictionary contains values of inapplicable type. This occurs when encountered; some invokations may happen before throwing.

◆ getOr() [1/2]

Data Parsnip::Data::getOr ( const std::string &  name,
const Data defvalue 
) const
inline

Specialization of getOr for Data.

Template Parameters
DatatypeThe desired return type of the data.
Parameters
nameThe name of the member to retrieve.
defvalueThe default to use if the member is not present.
Exceptions
IncorrectDataTypeif the object is not a dictionary.

◆ getOr() [2/2]

template<typename Datatype >
Datatype Parsnip::Data::getOr ( const std::string &  name,
const Datatype &  defvalue 
) const
inline

Extract a value if a member exists, otherwise use a default.

Template Parameters
DatatypeThe desired return type of the data.
Parameters
nameThe name of the member to retrieve.
defvalueThe default to use if the member is not present.
Exceptions
IncorrectDataTypeif the object is not a dictionary, or the item is present but not the desired type.

◆ isNull()

bool Parsnip::Data::isNull ( void  ) const
inlinenoexcept

Check if data contains a value.

Returns
True if empty, false otherwise.

◆ make_dictionary()

template<typename T = Data>
static Data Parsnip::Data::make_dictionary ( std::initializer_list< std::pair< const char *, const T >>  initial_data)
inlinestatic

Dictionary factory.

Parameters
initial_dataName-value pairs to be inserted into the dictionary.
Warning
Initializer lists cannot use rvalue references; hence, elements are copied. This is fine for simple items, but should be avoided when inserting complicatated structures. Prefer move assignment or Parsnip::Data (Parsnip::Data::Dictionary, ...).

◆ make_list()

template<typename... T>
static Data Parsnip::Data::make_list ( T &&...  params)
inlinestatic

List factory.

Parameters are inserted in order as list members.

◆ makeFlexible()

const Data & Parsnip::Data::makeFlexible ( ) const

IF a data item is a string, change it to a flexible string.

Use of this function should be very rare; strings should be strings and numbers numbers. But if a number gets stored in a string, this allows it to be accessed until it can be fixed (and it tolerates fixing, too).

◆ operator==()

bool Parsnip::Data::operator== ( const Data compare) const

Compare two structures.

Parameters
compareThe structure to compare to.
Returns
True if identical, false otherwise.

◆ operator[]() [1/4]

Data & Parsnip::Data::operator[] ( const std::string &  key)

Dictionary member accessor.

If dictionary is NOT constant, accessing non-existent key creates it.

◆ operator[]() [2/4]

const Data & Parsnip::Data::operator[] ( const std::string &  key) const

Dictionary member accessor.

If dictionary is constant, avoid automatic insertion, and throw error if key is not present in dictionary.

◆ operator[]() [3/4]

Data & Parsnip::Data::operator[] ( size_type  index)

List member accessor.

If list is NOT constant, accessing outside of range expands list size

◆ operator[]() [4/4]

const Data & Parsnip::Data::operator[] ( size_type  index) const

List member accessor.

If list is constant, avoid automatic insertion, and throw error if index is out of range.

◆ size()

Data::size_type Parsnip::Data::size ( ) const

Retrieve number of entries in a list.

Returns
Count of values in list.
Exceptions
IncorrectDataTypeif not a list.

◆ toJson() [1/2]

std::string Parsnip::Data::toJson ( int  indent = NoIndent) const

Return serial data encoded using JSON.

Parameters
indentStarting indentation for elements.
Returns
A string.

◆ toJson() [2/2]

std::ostream & Parsnip::Data::toJson ( std::ostream &  target,
int  indent = NoIndent,
bool  suppress = false 
) const

Write serial data encoded using JSON.

Parameters
targetStream to which to write data.
indentStarting indentation for elements.
suppressIf true, suppress indent on first line.
Returns
The output stream.

◆ toList()

template<typename Datatype >
std::vector<Datatype> Parsnip::Data::toList ( ) const
inline

Return a list or a single item in a container.

Template Parameters
ContainerA standard (-like) container, such as std::vector <std::string>. Member typedef Container::value_type determines the inner type. If this object is a list, the container is populated with the list contents; otherwise, it is populated with the single data item.
Exceptions
IncorrectDataTypeif this object is neither a list nor the expected type, or if it is a list but some members are not the expected type.

◆ type_name()

const char * Parsnip::Data::type_name ( Type  ty)
static

Return the name corresponding to a type.

Parameters
tyThe type whose name to retrieve.
Returns
The name of the type.

The documentation for this class was generated from the following files: