Merge branch 'noboost'

This commit is contained in:
Tristan Penman 2016-08-15 22:34:18 -07:00
commit 07690e070e
37 changed files with 1805 additions and 528 deletions

View File

@ -4,14 +4,6 @@ dist: trusty
matrix: matrix:
include: include:
- os: linux
compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9', 'valgrind', 'python-pip', 'python-yaml']
env: COMPILER=g++-4.9
- os: linux - os: linux
compiler: gcc compiler: gcc
addons: addons:

View File

@ -18,3 +18,6 @@ Michael Smith, michael.smith@puppetlabs.com
Richard Clamp, richardc@unixbeard.net Richard Clamp, richardc@unixbeard.net
Boost-related fixes Boost-related fixes
Lars Immisch, lars@ibp.de
noboost branch

View File

@ -7,18 +7,13 @@ option (BUILD_TESTS "Build valijson Tests." TRUE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall ")
if (BUILD_TESTS OR BUILD_EXAMPLES) if (BUILD_TESTS OR BUILD_EXAMPLES)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
if(VALIJSON_CXX11_ADAPTERS STREQUAL "disabled")
message(STATUS "Building with C++11 support disabled") include(CheckCXXCompilerFlag)
else() CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
include(CheckCXXCompilerFlag) if(COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(VALIJSON_CXX11_ADAPTERS_ARE_ENABLED 1)
message(STATUS "Building with C++11 support enabled")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DVALIJSON_BUILD_CXX11_ADAPTERS=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DVALIJSON_BUILD_CXX11_ADAPTERS=1")
else() else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
endif() endif()
add_definitions(-DBOOST_ALL_DYN_LINK) add_definitions(-DBOOST_ALL_DYN_LINK)
@ -26,7 +21,7 @@ set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON) set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF) set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost 1.55.0 COMPONENTS regex REQUIRED) find_package(Boost 1.54.0 REQUIRED)
# jsoncpp library # jsoncpp library
add_library(jsoncpp add_library(jsoncpp
@ -35,11 +30,23 @@ add_library(jsoncpp
thirdparty/jsoncpp-0.9.4/src/lib_json/json_writer.cpp thirdparty/jsoncpp-0.9.4/src/lib_json/json_writer.cpp
) )
if(VALIJSON_CXX11_ADAPTERS_ARE_ENABLED) target_include_directories(jsoncpp SYSTEM PRIVATE
add_library(json11 thirdparty/jsoncpp-0.9.4/include
)
set_target_properties(jsoncpp PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/jsoncpp-0.9.4)
add_library(json11
thirdparty/json11-2016-01-26/json11.cpp thirdparty/json11-2016-01-26/json11.cpp
) )
endif()
target_include_directories(json11 SYSTEM PRIVATE
thirdparty/json11-2016-01-26
)
set_target_properties(json11 PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/json11-2016-01-26)
# Build local gtest # Build local gtest
set(gtest_force_shared_crt ON) set(gtest_force_shared_crt ON)
@ -51,18 +58,14 @@ include_directories(
) )
include_directories(SYSTEM include_directories(SYSTEM
${Boost_INCLUDE_DIRS}
thirdparty/gtest-1.7.0/include thirdparty/gtest-1.7.0/include
thirdparty/json11-2016-01-26
thirdparty/jsoncpp-0.9.4/include thirdparty/jsoncpp-0.9.4/include
thirdparty/rapidjson-1.0.2/include thirdparty/rapidjson-1.0.2/include
thirdparty/picojson-1.3.0 thirdparty/picojson-1.3.0
thirdparty/nlohmann-json-1.1.0 thirdparty/nlohmann-json-1.1.0
${Boost_INCLUDE_DIRS}
) )
if(VALIJSON_CXX11_ADAPTERS_ARE_ENABLED)
include_directories(SYSTEM
thirdparty/json11-2016-01-26
)
endif()
# Custom schema validation example # Custom schema validation example
add_executable(custom_schema add_executable(custom_schema
@ -78,22 +81,16 @@ set(TEST_SOURCES
tests/test_adapter_comparison.cpp tests/test_adapter_comparison.cpp
tests/test_fetch_document_callback.cpp tests/test_fetch_document_callback.cpp
tests/test_json_pointer.cpp tests/test_json_pointer.cpp
tests/test_json11_adapter.cpp
tests/test_jsoncpp_adapter.cpp tests/test_jsoncpp_adapter.cpp
tests/test_nlohmann_json_adapter.cpp
tests/test_property_tree_adapter.cpp tests/test_property_tree_adapter.cpp
tests/test_rapidjson_adapter.cpp tests/test_rapidjson_adapter.cpp
tests/test_picojson_adapter.cpp tests/test_picojson_adapter.cpp
tests/test_validation_errors.cpp tests/test_validation_errors.cpp
tests/test_validator.cpp tests/test_validator.cpp
tests/test_poly_constraint.cpp tests/test_poly_constraint.cpp
) )
if(VALIJSON_CXX11_ADAPTERS_ARE_ENABLED)
set(TEST_SOURCES
${TEST_SOURCES}
tests/test_json11_adapter.cpp
tests/test_nlohmann_json_adapter.cpp
)
endif()
# Unit tests executable # Unit tests executable
add_executable(test_suite ${TEST_SOURCES}) add_executable(test_suite ${TEST_SOURCES})
@ -103,10 +100,7 @@ set_target_properties(test_suite
PROPERTIES COMPILE_DEFINITIONS "PICOJSON_USE_INT64" PROPERTIES COMPILE_DEFINITIONS "PICOJSON_USE_INT64"
) )
set(TEST_LIBS gtest gtest_main jsoncpp) set(TEST_LIBS gtest gtest_main jsoncpp json11)
if(VALIJSON_CXX11_ADAPTERS_ARE_ENABLED)
set(TEST_LIBS ${TEST_LIBS} json11)
endif()
target_link_libraries(test_suite ${TEST_LIBS} ${Boost_LIBRARIES}) target_link_libraries(test_suite ${TEST_LIBS} ${Boost_LIBRARIES})
target_link_libraries(custom_schema ${Boost_LIBRARIES}) target_link_libraries(custom_schema ${Boost_LIBRARIES})

View File

@ -2,13 +2,13 @@
## Overview ## ## Overview ##
Valijson is a header-only [JSON Schema](http://json-schema.org/) Validation library for C++. Valijson is a header-only [JSON Schema](http://json-schema.org/) Validation library for C++11.
Valijson provides a simple validation API that allows you load JSON Schemas, and validate documents loaded by one of several supported parser libraries. Valijson provides a simple validation API that allows you load JSON Schemas, and validate documents loaded by one of several supported parser libraries.
## Project Goals ## ## Project Goals ##
The goal of this project is to support validation of all constraints available in JSON Schema v4, while being competitive with the performance of hand-written JSON validators. The goal of this project is to support validation of all constraints available in JSON Schema v4, while being competitive with the performance of a hand-written schema validator.
## Usage ## ## Usage ##
@ -104,9 +104,9 @@ Things get more interesting when you build a schema using custom code, as illust
## JSON References ## ## JSON References ##
The library includes support for local JSON References, as well as remote JSON References when the appropriate callback functions are provided. The library includes support for local JSON References. Remote JSON References are supported only when the appropriate callback functions are provided.
Two callback functions are required. The first is expected to return a pointer to a newly fetched document. Valijson takes ownership of this pointer. The second callback function is used to release ownership of that pointer back to the application. Typically, this would immediately free the memory that was allocated for the document. Valijson's JSON Reference implementation requires that two callback functions are required. The first is expected to return a pointer to a newly fetched document. Valijson takes ownership of this pointer. The second callback function is used to release ownership of that pointer back to the application. Typically, this would immediately free the memory that was allocated for the document.
## Test Suite ## ## Test Suite ##
@ -160,11 +160,7 @@ Doxygen documentation can be built by running 'doxygen' from the project root di
## Dependencies ## ## Dependencies ##
Required: Valijson requires a compiler with robust C++11 support.
- boost 1.54
Later versions of boost (up to 1.59) are also known to work correctly.
## Supported Parsers ## ## Supported Parsers ##
@ -177,11 +173,17 @@ Valijson supports JSON documents loaded using JsonCpp, RapidJson, Boost Property
- [rapidjson 1.0.2](https://github.com/miloyip/rapidjson/releases/tag/v1.0.2) - [rapidjson 1.0.2](https://github.com/miloyip/rapidjson/releases/tag/v1.0.2)
- [PicoJSON 1.3.0](https://github.com/kazuho/picojson/archive/v1.3.0.tar.gz) - [PicoJSON 1.3.0](https://github.com/kazuho/picojson/archive/v1.3.0.tar.gz)
Version of JsonCpp going back to 0.5.0 should also work correctly, but versions from 1.0 onwards have not yet been tested. Other versions of these libraries may work, but have not been tested. In particular, versions of JsonCpp going back to 0.5.0 should also work correctly, but versions from 1.0 onwards have not yet been tested.
Also note that when using PicoJSON, it may be necessary to include the `picojson.h` before other headers to ensure that the appropriate macros have been enabled. ## Test Suite Requirements ##
Other versions of these libraries may work, but have not been tested. Supported versions of these libraries have been included in the 'thirdparty' directory so as to support Valijson's examples and test suite.
The only exception to this is boost, which due to its sheer size must be installed to a location that CMake can find.
## Known Issues ##
Note that when using PicoJSON, it may be necessary to include the `picojson.h` before other headers to ensure that the appropriate macros have been enabled.
## License ## ## License ##

View File

@ -210,7 +210,7 @@ int main(int argc, char *argv[])
while (results.popError(error)) { while (results.popError(error)) {
cerr << "Error #" << errorNum << std::endl; cerr << "Error #" << errorNum << std::endl;
cerr << " "; cerr << " ";
BOOST_FOREACH( const std::string contextElement, error.context ) { for (const std::string &contextElement : error.context) {
cerr << contextElement << " "; cerr << contextElement << " ";
} }
cerr << endl; cerr << endl;

1042
include/compat/optional.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
#ifndef __VALIJSON_ADAPTERS_ADAPTER_HPP #ifndef __VALIJSON_ADAPTERS_ADAPTER_HPP
#define __VALIJSON_ADAPTERS_ADAPTER_HPP #define __VALIJSON_ADAPTERS_ADAPTER_HPP
#include <boost/function.hpp> #include <functional>
namespace valijson { namespace valijson {
namespace adapters { namespace adapters {
@ -26,11 +26,11 @@ class Adapter
public: public:
/// Typedef for callback function supplied to applyToArray. /// Typedef for callback function supplied to applyToArray.
typedef boost::function<bool (const Adapter &)> typedef std::function<bool (const Adapter &)>
ArrayValueCallback; ArrayValueCallback;
/// Typedef for callback function supplied to applyToObject. /// Typedef for callback function supplied to applyToObject.
typedef boost::function<bool (const std::string &, const Adapter &)> typedef std::function<bool (const std::string &, const Adapter &)>
ObjectMemberCallback; ObjectMemberCallback;
/** /**

View File

@ -5,15 +5,48 @@
#include <stdint.h> #include <stdint.h>
#include <sstream> #include <sstream>
#include <boost/foreach.hpp> // This should be removed once C++17 is widely available
#include <boost/lexical_cast.hpp> #if __has_include(<optional>)
#include <boost/optional.hpp> # include <optional>
namespace opt = std;
#else
# include <compat/optional.hpp>
namespace opt = std::experimental;
#endif
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
namespace valijson { namespace valijson {
namespace adapters { namespace adapters {
/**
* @brief A helper for the array and object member iterators.
*
* See http://www.stlsoft.org/doc-1.9/group__group____pattern____dereference__proxy.html
* for motivation
*
* @tparam Value Name of the value type
*/
template<class Value>
struct DerefProxy
{
explicit DerefProxy(const Value& x)
: m_ref(x) { }
Value* operator->()
{
return std::addressof(m_ref);
}
operator Value*()
{
return std::addressof(m_ref);
}
private:
Value m_ref;
};
/** /**
* @brief Template class that implements the expected semantics of an Adapter. * @brief Template class that implements the expected semantics of an Adapter.
* *
@ -215,8 +248,8 @@ public:
// effort of constructing an ArrayType instance if the value is // effort of constructing an ArrayType instance if the value is
// definitely an array. // definitely an array.
if (value.isArray()) { if (value.isArray()) {
const boost::optional<Array> array = value.getArrayOptional(); const opt::optional<Array> array = value.getArrayOptional();
BOOST_FOREACH( const AdapterType element, *array ) { for (const AdapterType element : *array) {
if (!fn(element)) { if (!fn(element)) {
return false; return false;
} }
@ -233,8 +266,8 @@ public:
} }
if (value.isObject()) { if (value.isObject()) {
const boost::optional<Object> object = value.getObjectOptional(); const opt::optional<Object> object = value.getObjectOptional();
BOOST_FOREACH( const ObjectMemberType member, *object ) { for (const ObjectMemberType member : *object) {
if (!fn(member.first, AdapterType(member.second))) { if (!fn(member.first, AdapterType(member.second))) {
return false; return false;
} }
@ -444,18 +477,14 @@ public:
} else if (value.isInteger()) { } else if (value.isInteger()) {
int64_t integerValue; int64_t integerValue;
if (value.getInteger(integerValue)) { if (value.getInteger(integerValue)) {
try { result = std::to_string(integerValue);
result = boost::lexical_cast<std::string>(integerValue);
return true; return true;
} catch (boost::bad_lexical_cast &) { }
} }
} else if (value.isDouble()) { } else if (value.isDouble()) {
double doubleValue; double doubleValue;
if (value.getDouble(doubleValue)) { if (value.getDouble(doubleValue)) {
try { result = std::to_string(doubleValue);
result = boost::lexical_cast<std::string>(doubleValue);
return true; return true;
} catch (boost::bad_lexical_cast &) { }
} }
} }
@ -482,7 +511,7 @@ public:
other.asString() == asString(); other.asString() == asString();
} else if (isArray()) { } else if (isArray()) {
if (other.isArray() && getArraySize() == other.getArraySize()) { if (other.isArray() && getArraySize() == other.getArraySize()) {
const boost::optional<ArrayType> array = value.getArrayOptional(); const opt::optional<ArrayType> array = value.getArrayOptional();
if (array) { if (array) {
ArrayComparisonFunctor fn(*array, strict); ArrayComparisonFunctor fn(*array, strict);
return other.applyToArray(fn); return other.applyToArray(fn);
@ -492,7 +521,7 @@ public:
} }
} else if (isObject()) { } else if (isObject()) {
if (other.isObject() && other.getObjectSize() == getObjectSize()) { if (other.isObject() && other.getObjectSize() == getObjectSize()) {
const boost::optional<ObjectType> object = value.getObjectOptional(); const opt::optional<ObjectType> object = value.getObjectOptional();
if (object) { if (object) {
ObjectComparisonFunctor fn(*object, strict); ObjectComparisonFunctor fn(*object, strict);
return other.applyToObject(fn); return other.applyToObject(fn);
@ -521,7 +550,7 @@ public:
*/ */
ArrayType getArray() const ArrayType getArray() const
{ {
boost::optional<ArrayType> arrayValue = value.getArrayOptional(); opt::optional<ArrayType> arrayValue = value.getArrayOptional();
if (arrayValue) { if (arrayValue) {
return *arrayValue; return *arrayValue;
} }
@ -630,7 +659,7 @@ public:
*/ */
ObjectType getObject() const ObjectType getObject() const
{ {
boost::optional<ObjectType> objectValue = value.getObjectOptional(); opt::optional<ObjectType> objectValue = value.getObjectOptional();
if (objectValue) { if (objectValue) {
return *objectValue; return *objectValue;
} }

View File

@ -29,8 +29,6 @@
#include <string> #include <string>
#include <json11.hpp> #include <json11.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp> #include <valijson/adapters/basic_adapter.hpp>
@ -289,18 +287,18 @@ public:
* @brief Optionally return a Json11Array instance. * @brief Optionally return a Json11Array instance.
* *
* If the referenced Json11 value is an array, this function will return * If the referenced Json11 value is an array, this function will return
* a boost::optional containing a Json11Array instance referencing the * a std::optional containing a Json11Array instance referencing the
* array. * array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<Json11Array> getArrayOptional() const opt::optional<Json11Array> getArrayOptional() const
{ {
if (value.is_array()) { if (value.is_array()) {
return boost::make_optional(Json11Array(value)); return opt::make_optional(Json11Array(value));
} }
return boost::none; return opt::optional<Json11Array>();
} }
/** /**
@ -357,18 +355,18 @@ public:
* @brief Optionally return a Json11Object instance. * @brief Optionally return a Json11Object instance.
* *
* If the referenced Json11 value is an object, this function will return a * If the referenced Json11 value is an object, this function will return a
* boost::optional containing a Json11Object instance referencing the * std::optional containing a Json11Object instance referencing the
* object. * object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<Json11Object> getObjectOptional() const opt::optional<Json11Object> getObjectOptional() const
{ {
if (value.is_object()) { if (value.is_object()) {
return boost::make_optional(Json11Object(value)); return opt::make_optional(Json11Object(value));
} }
return boost::none; return opt::optional<Json11Object>();
} }
/** /**
@ -498,11 +496,9 @@ public:
* @see Json11Array * @see Json11Array
*/ */
class Json11ArrayValueIterator: class Json11ArrayValueIterator:
public boost::iterator_facade< public std::iterator<
Json11ArrayValueIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
Json11Adapter, // value type Json11Adapter> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
Json11Adapter> // type returned when dereferenced
{ {
public: public:
@ -518,11 +514,16 @@ public:
/// Returns a Json11Adapter that contains the value of the current /// Returns a Json11Adapter that contains the value of the current
/// element. /// element.
Json11Adapter dereference() const Json11Adapter operator*() const
{ {
return Json11Adapter(*itr); return Json11Adapter(*itr);
} }
DerefProxy<Json11Adapter> operator->() const
{
return DerefProxy<Json11Adapter>(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -534,19 +535,35 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const Json11ArrayValueIterator &other) const bool operator==(const Json11ArrayValueIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const Json11ArrayValueIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const Json11ArrayValueIterator& operator++()
{
itr++;
return *this;
}
Json11ArrayValueIterator operator++(int)
{
Json11ArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const Json11ArrayValueIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -570,11 +587,9 @@ private:
* @see Json11ObjectMember * @see Json11ObjectMember
*/ */
class Json11ObjectMemberIterator: class Json11ObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
Json11ObjectMemberIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
Json11ObjectMember, // value type Json11ObjectMember> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
Json11ObjectMember> // type returned when dereferenced
{ {
public: public:
@ -591,11 +606,16 @@ public:
* @brief Returns a Json11ObjectMember that contains the key and value * @brief Returns a Json11ObjectMember that contains the key and value
* belonging to the object member identified by the iterator. * belonging to the object member identified by the iterator.
*/ */
Json11ObjectMember dereference() const Json11ObjectMember operator*() const
{ {
return Json11ObjectMember(itr->first, itr->second); return Json11ObjectMember(itr->first, itr->second);
} }
DerefProxy<Json11ObjectMember> operator->() const
{
return DerefProxy<Json11ObjectMember>(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -607,19 +627,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const Json11ObjectMemberIterator &other) const bool operator==(const Json11ObjectMemberIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const Json11ObjectMemberIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const Json11ObjectMemberIterator& operator++()
{
itr++;
return *this;
}
Json11ObjectMemberIterator operator++(int)
{
Json11ObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const Json11ObjectMemberIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
private: private:

View File

@ -29,8 +29,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <boost/bind.hpp> #include <iterator>
#include <boost/iterator/iterator_facade.hpp>
#include <json/json.h> #include <json/json.h>
@ -284,18 +283,18 @@ public:
* @brief Optionally return a JsonCppArray instance. * @brief Optionally return a JsonCppArray instance.
* *
* If the referenced JsonCpp value is an array, this function will return a * If the referenced JsonCpp value is an array, this function will return a
* boost::optional containing a JsonCppArray instance referencing the * std::optional containing a JsonCppArray instance referencing the
* array. * array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<JsonCppArray> getArrayOptional() const opt::optional<JsonCppArray> getArrayOptional() const
{ {
if (value.isArray()) { if (value.isArray()) {
return boost::make_optional(JsonCppArray(value)); return opt::make_optional(JsonCppArray(value));
} }
return boost::none; return opt::optional<JsonCppArray>();
} }
/** /**
@ -353,18 +352,18 @@ public:
* @brief Optionally return a JsonCppObject instance. * @brief Optionally return a JsonCppObject instance.
* *
* If the referenced JsonCpp value is an object, this function will return a * If the referenced JsonCpp value is an object, this function will return a
* boost::optional containing a JsonCppObject instance referencing the * std::optional containing a JsonCppObject instance referencing the
* object. * object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<JsonCppObject> getObjectOptional() const opt::optional<JsonCppObject> getObjectOptional() const
{ {
if (value.isObject()) { if (value.isObject()) {
return boost::make_optional(JsonCppObject(value)); return opt::make_optional(JsonCppObject(value));
} }
return boost::none; return opt::optional<JsonCppObject>();
} }
/** /**
@ -493,12 +492,11 @@ public:
* @see JsonCppArray * @see JsonCppArray
*/ */
class JsonCppArrayValueIterator: class JsonCppArrayValueIterator:
public boost::iterator_facade< public std::iterator<
JsonCppArrayValueIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
JsonCppAdapter, // value type JsonCppAdapter> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
JsonCppAdapter> // type returned when dereferenced
{ {
public: public:
/** /**
@ -511,11 +509,16 @@ public:
: itr(itr) { } : itr(itr) { }
/// Returns a JsonCppAdapter that contains the value of the current element. /// Returns a JsonCppAdapter that contains the value of the current element.
JsonCppAdapter dereference() const JsonCppAdapter operator*() const
{ {
return JsonCppAdapter(*itr); return JsonCppAdapter(*itr);
} }
DerefProxy<JsonCppAdapter> operator->() const
{
return DerefProxy<JsonCppAdapter>(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -527,19 +530,35 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const JsonCppArrayValueIterator &rhs) const bool operator==(const JsonCppArrayValueIterator &rhs) const
{ {
return itr == rhs.itr; return itr == rhs.itr;
} }
void increment() bool operator!=(const JsonCppArrayValueIterator &rhs) const
{ {
itr++; return !(itr == rhs.itr);
} }
void decrement() JsonCppArrayValueIterator& operator++()
{
itr++;
return *this;
}
JsonCppArrayValueIterator operator++(int)
{
JsonCppArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
JsonCppArrayValueIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -571,11 +590,9 @@ private:
* @see JsonCppObjectMember * @see JsonCppObjectMember
*/ */
class JsonCppObjectMemberIterator: class JsonCppObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
JsonCppObjectMemberIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
JsonCppObjectMember, // value type JsonCppObjectMember> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
JsonCppObjectMember> // type returned when dereferenced
{ {
public: public:
@ -591,11 +608,16 @@ public:
* @brief Returns a JsonCppObjectMember that contains the key and value * @brief Returns a JsonCppObjectMember that contains the key and value
* belonging to the object member identified by the iterator. * belonging to the object member identified by the iterator.
*/ */
JsonCppObjectMember dereference() const JsonCppObjectMember operator*() const
{ {
return JsonCppObjectMember(itr.key().asString(), *itr); return JsonCppObjectMember(itr.key().asString(), *itr);
} }
DerefProxy<JsonCppObjectMember> operator->() const
{
return DerefProxy<JsonCppObjectMember>(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -607,19 +629,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const JsonCppObjectMemberIterator &rhs) const bool operator==(const JsonCppObjectMemberIterator &rhs) const
{ {
return itr == rhs.itr; return itr == rhs.itr;
} }
void increment() bool operator!=(const JsonCppObjectMemberIterator &rhs) const
{ {
itr++; return !(itr == rhs.itr);
} }
void decrement() const JsonCppObjectMemberIterator& operator++()
{
itr++;
return *this;
}
JsonCppObjectMemberIterator operator++(int)
{
JsonCppObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
JsonCppObjectMemberIterator operator--()
{ {
itr--; itr--;
return *this;
} }
private: private:

View File

@ -29,8 +29,6 @@
#include <string> #include <string>
#include <json.hpp> #include <json.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
#include <valijson/adapters/basic_adapter.hpp> #include <valijson/adapters/basic_adapter.hpp>
@ -291,18 +289,18 @@ public:
* @brief Optionally return a NlohmannJsonArray instance. * @brief Optionally return a NlohmannJsonArray instance.
* *
* If the referenced NlohmannJson value is an array, this function will return * If the referenced NlohmannJson value is an array, this function will return
* a boost::optional containing a NlohmannJsonArray instance referencing the * a std::optional containing a NlohmannJsonArray instance referencing the
* array. * array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<NlohmannJsonArray> getArrayOptional() const opt::optional<NlohmannJsonArray> getArrayOptional() const
{ {
if (value.is_array()) { if (value.is_array()) {
return boost::make_optional(NlohmannJsonArray(value)); return opt::make_optional(NlohmannJsonArray(value));
} }
return boost::none; return opt::optional<NlohmannJsonArray>();
} }
/** /**
@ -359,18 +357,18 @@ public:
* @brief Optionally return a NlohmannJsonObject instance. * @brief Optionally return a NlohmannJsonObject instance.
* *
* If the referenced NlohmannJson value is an object, this function will return a * If the referenced NlohmannJson value is an object, this function will return a
* boost::optional containing a NlohmannJsonObject instance referencing the * std::optional containing a NlohmannJsonObject instance referencing the
* object. * object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<NlohmannJsonObject> getObjectOptional() const opt::optional<NlohmannJsonObject> getObjectOptional() const
{ {
if (value.is_object()) { if (value.is_object()) {
return boost::make_optional(NlohmannJsonObject(value)); return opt::make_optional(NlohmannJsonObject(value));
} }
return boost::none; return opt::optional<NlohmannJsonObject>();
} }
/** /**
@ -498,11 +496,9 @@ public:
* @see NlohmannJsonArray * @see NlohmannJsonArray
*/ */
class NlohmannJsonArrayValueIterator: class NlohmannJsonArrayValueIterator:
public boost::iterator_facade< public std::iterator<
NlohmannJsonArrayValueIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
NlohmannJsonAdapter, // value type NlohmannJsonAdapter> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
NlohmannJsonAdapter> // type returned when dereferenced
{ {
public: public:
@ -517,11 +513,16 @@ public:
/// Returns a NlohmannJsonAdapter that contains the value of the current /// Returns a NlohmannJsonAdapter that contains the value of the current
/// element. /// element.
NlohmannJsonAdapter dereference() const NlohmannJsonAdapter operator*() const
{ {
return NlohmannJsonAdapter(*itr); return NlohmannJsonAdapter(*itr);
} }
DerefProxy<NlohmannJsonAdapter> operator->() const
{
return DerefProxy<NlohmannJsonAdapter>(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -533,19 +534,35 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const NlohmannJsonArrayValueIterator &other) const bool operator==(const NlohmannJsonArrayValueIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const NlohmannJsonArrayValueIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const NlohmannJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
NlohmannJsonArrayValueIterator operator++(int)
{
NlohmannJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const NlohmannJsonArrayValueIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -569,11 +586,9 @@ private:
* @see NlohmannJsonObjectMember * @see NlohmannJsonObjectMember
*/ */
class NlohmannJsonObjectMemberIterator: class NlohmannJsonObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
NlohmannJsonObjectMemberIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
NlohmannJsonObjectMember, // value type NlohmannJsonObjectMember> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
NlohmannJsonObjectMember> // type returned when dereferenced
{ {
public: public:
@ -589,11 +604,16 @@ public:
* @brief Returns a NlohmannJsonObjectMember that contains the key and value * @brief Returns a NlohmannJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator. * belonging to the object member identified by the iterator.
*/ */
NlohmannJsonObjectMember dereference() const NlohmannJsonObjectMember operator*() const
{ {
return NlohmannJsonObjectMember(itr.key(), itr.value()); return NlohmannJsonObjectMember(itr.key(), itr.value());
} }
DerefProxy<NlohmannJsonObjectMember> operator->() const
{
return DerefProxy<NlohmannJsonObjectMember>(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -605,19 +625,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const NlohmannJsonObjectMemberIterator &other) const bool operator==(const NlohmannJsonObjectMemberIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const NlohmannJsonObjectMemberIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const NlohmannJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
NlohmannJsonObjectMemberIterator operator++(int)
{
NlohmannJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const NlohmannJsonObjectMemberIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
private: private:

View File

@ -28,9 +28,6 @@
#define __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP #define __VALIJSON_ADAPTERS_PICOJSON_ADAPTER_HPP
#include <string> #include <string>
#include <boost/bind.hpp>
#include <boost/optional.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <picojson.h> #include <picojson.h>
@ -293,18 +290,18 @@ public:
* @brief Optionally return a PicoJsonArray instance. * @brief Optionally return a PicoJsonArray instance.
* *
* If the referenced PicoJson value is an array, this function will return * If the referenced PicoJson value is an array, this function will return
* a boost::optional containing a PicoJsonArray instance referencing the * a std::optional containing a PicoJsonArray instance referencing the
* array. * array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<PicoJsonArray> getArrayOptional() const opt::optional<PicoJsonArray> getArrayOptional() const
{ {
if (value.is<picojson::array>()) { if (value.is<picojson::array>()) {
return boost::make_optional(PicoJsonArray(value)); return opt::make_optional(PicoJsonArray(value));
} }
return boost::none; return opt::optional<PicoJsonArray>();
} }
/** /**
@ -363,18 +360,18 @@ public:
* @brief Optionally return a PicoJsonObject instance. * @brief Optionally return a PicoJsonObject instance.
* *
* If the referenced PicoJson value is an object, this function will return a * If the referenced PicoJson value is an object, this function will return a
* boost::optional containing a PicoJsonObject instance referencing the * std::optional containing a PicoJsonObject instance referencing the
* object. * object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<PicoJsonObject> getObjectOptional() const opt::optional<PicoJsonObject> getObjectOptional() const
{ {
if (value.is<picojson::object>()) { if (value.is<picojson::object>()) {
return boost::make_optional(PicoJsonObject(value)); return opt::make_optional(PicoJsonObject(value));
} }
return boost::none; return opt::optional<PicoJsonObject>();
} }
/** /**
@ -503,16 +500,14 @@ public:
* *
* This class provides a JSON array iterator that dereferences as an instance of * This class provides a JSON array iterator that dereferences as an instance of
* PicoJsonAdapter representing a value stored in the array. It has been * PicoJsonAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template. * implemented using the std::iterator template.
* *
* @see PicoJsonArray * @see PicoJsonArray
*/ */
class PicoJsonArrayValueIterator: class PicoJsonArrayValueIterator:
public boost::iterator_facade< public std::iterator<
PicoJsonArrayValueIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
PicoJsonAdapter, // value type PicoJsonAdapter> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
PicoJsonAdapter> // type returned when dereferenced
{ {
public: public:
@ -528,11 +523,16 @@ public:
/// Returns a PicoJsonAdapter that contains the value of the current /// Returns a PicoJsonAdapter that contains the value of the current
/// element. /// element.
PicoJsonAdapter dereference() const PicoJsonAdapter operator*() const
{ {
return PicoJsonAdapter(*itr); return PicoJsonAdapter(*itr);
} }
DerefProxy<PicoJsonAdapter> operator->() const
{
return DerefProxy<PicoJsonAdapter>(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -544,19 +544,35 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const PicoJsonArrayValueIterator &other) const bool operator==(const PicoJsonArrayValueIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const PicoJsonArrayValueIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const PicoJsonArrayValueIterator& operator++()
{
itr++;
return *this;
}
PicoJsonArrayValueIterator operator++(int)
{
PicoJsonArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PicoJsonArrayValueIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -580,11 +596,9 @@ private:
* @see PicoJsonObjectMember * @see PicoJsonObjectMember
*/ */
class PicoJsonObjectMemberIterator: class PicoJsonObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
PicoJsonObjectMemberIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
PicoJsonObjectMember, // value type PicoJsonObjectMember> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
PicoJsonObjectMember> // type returned when dereferenced
{ {
public: public:
@ -601,11 +615,16 @@ public:
* @brief Returns a PicoJsonObjectMember that contains the key and value * @brief Returns a PicoJsonObjectMember that contains the key and value
* belonging to the object member identified by the iterator. * belonging to the object member identified by the iterator.
*/ */
PicoJsonObjectMember dereference() const PicoJsonObjectMember operator*() const
{ {
return PicoJsonObjectMember(itr->first, itr->second); return PicoJsonObjectMember(itr->first, itr->second);
} }
DerefProxy<PicoJsonObjectMember> operator->() const
{
return DerefProxy<PicoJsonObjectMember>(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -617,19 +636,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const PicoJsonObjectMemberIterator &other) const bool operator==(const PicoJsonObjectMemberIterator &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const PicoJsonObjectMemberIterator &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() const PicoJsonObjectMemberIterator& operator++()
{
itr++;
return *this;
}
PicoJsonObjectMemberIterator operator++(int)
{
PicoJsonObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PicoJsonObjectMemberIterator& operator--(int)
{ {
itr--; itr--;
return *this;
} }
private: private:

View File

@ -28,8 +28,7 @@
#define __VALIJSON_ADAPTERS_PROPERTY_TREE_ADAPTER_HPP #define __VALIJSON_ADAPTERS_PROPERTY_TREE_ADAPTER_HPP
#include <string> #include <string>
#include <boost/bind.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
@ -281,7 +280,7 @@ public:
{ {
if (tree.data().empty()) { // No string content if (tree.data().empty()) { // No string content
if (tree.size() == 0) { // No children if (tree.size() == 0) { // No children
array = tree; // Treat as empty array array.emplace(tree); // Treat as empty array
} else { } else {
bool isArray = true; bool isArray = true;
boost::property_tree::ptree::const_iterator itr; boost::property_tree::ptree::const_iterator itr;
@ -293,9 +292,9 @@ public:
} }
if (isArray) { if (isArray) {
array = tree; array.emplace(tree);
} else { } else {
object = tree; object.emplace(tree);
} }
} }
} else { } else {
@ -325,18 +324,18 @@ public:
* @brief Return an instance of PropertyTreeArrayAdapter. * @brief Return an instance of PropertyTreeArrayAdapter.
* *
* If the referenced property tree value is an array, this function will * If the referenced property tree value is an array, this function will
* return a boost::optional containing a PropertyTreeArray instance * return a std::optional containing a PropertyTreeArray instance
* referencing the array. * referencing the array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<PropertyTreeArray> getArrayOptional() const opt::optional<PropertyTreeArray> getArrayOptional() const
{ {
if (array) { if (array) {
return boost::make_optional(PropertyTreeArray(*array)); return opt::make_optional(PropertyTreeArray(*array));
} }
return boost::none; return opt::optional<PropertyTreeArray>();
} }
/** /**
@ -379,18 +378,18 @@ public:
* @brief Optionally return a PropertyTreeObject instance. * @brief Optionally return a PropertyTreeObject instance.
* *
* If the referenced property tree is an object, this function will return a * If the referenced property tree is an object, this function will return a
* boost::optional containing a PropertyTreeObject instance referencing the * std::optional containing a PropertyTreeObject instance referencing the
* object. * object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<PropertyTreeObject> getObjectOptional() const opt::optional<PropertyTreeObject> getObjectOptional() const
{ {
if (object) { if (object) {
return boost::make_optional(PropertyTreeObject(*object)); return opt::make_optional(PropertyTreeObject(*object));
} }
return boost::none; return opt::optional<PropertyTreeObject>();
} }
/** /**
@ -431,7 +430,7 @@ public:
bool isArray() const bool isArray() const
{ {
return array != boost::none; return static_cast<bool>(array);
} }
bool isBool() const bool isBool() const
@ -461,12 +460,12 @@ public:
bool isObject() const bool isObject() const
{ {
return object != boost::none; return static_cast<bool>(object);
} }
bool isString() const bool isString() const
{ {
return value != boost::none; return static_cast<bool>(value);
} }
private: private:
@ -478,13 +477,13 @@ private:
} }
/// Reference used if the value is known to be an array /// Reference used if the value is known to be an array
boost::optional<const boost::property_tree::ptree &> array; opt::optional<const boost::property_tree::ptree &> array;
/// Reference used if the value is known to be an object /// Reference used if the value is known to be an object
boost::optional<const boost::property_tree::ptree &> object; opt::optional<const boost::property_tree::ptree &> object;
/// Reference used if the value is known to be a POD type /// Reference used if the value is known to be a POD type
boost::optional<std::string> value; opt::optional<std::string> value;
}; };
/** /**
@ -525,11 +524,9 @@ public:
* @see PropertyTreeArray * @see PropertyTreeArray
*/ */
class PropertyTreeArrayValueIterator: class PropertyTreeArrayValueIterator:
public boost::iterator_facade< public std::iterator<
PropertyTreeArrayValueIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
PropertyTreeAdapter, // value type PropertyTreeAdapter> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
PropertyTreeAdapter> // type returned when dereferenced
{ {
public: public:
@ -545,11 +542,16 @@ public:
/// Returns a PropertyTreeAdapter that contains the value of the current /// Returns a PropertyTreeAdapter that contains the value of the current
/// element. /// element.
PropertyTreeAdapter dereference() const PropertyTreeAdapter operator*() const
{ {
return PropertyTreeAdapter(itr->second); return PropertyTreeAdapter(itr->second);
} }
DerefProxy<PropertyTreeAdapter> operator->() const
{
return DerefProxy<PropertyTreeAdapter>(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -561,19 +563,35 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const PropertyTreeArrayValueIterator &rhs) const bool operator==(const PropertyTreeArrayValueIterator &rhs) const
{ {
return itr == rhs.itr; return itr == rhs.itr;
} }
void increment() bool operator!=(const PropertyTreeArrayValueIterator &rhs) const
{ {
itr++; return !(itr == rhs.itr);
} }
void decrement() const PropertyTreeArrayValueIterator& operator++()
{
itr++;
return *this;
}
PropertyTreeArrayValueIterator operator++(int)
{
PropertyTreeArrayValueIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PropertyTreeArrayValueIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -605,11 +623,9 @@ private:
* @see PropertyTreeObjectMember * @see PropertyTreeObjectMember
*/ */
class PropertyTreeObjectMemberIterator: class PropertyTreeObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
PropertyTreeObjectMemberIterator, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
PropertyTreeObjectMember, // value type PropertyTreeObjectMember> // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
PropertyTreeObjectMember> // type returned when dereferenced
{ {
public: public:
@ -626,11 +642,16 @@ public:
* @brief Returns a PropertyTreeObjectMember that contains the key and * @brief Returns a PropertyTreeObjectMember that contains the key and
* value belonging to the object member identified by the iterator. * value belonging to the object member identified by the iterator.
*/ */
PropertyTreeObjectMember dereference() const PropertyTreeObjectMember operator*() const
{ {
return PropertyTreeObjectMember(itr->first, itr->second); return PropertyTreeObjectMember(itr->first, itr->second);
} }
DerefProxy<PropertyTreeObjectMember> operator->() const
{
return DerefProxy<PropertyTreeObjectMember>(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -642,19 +663,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const PropertyTreeObjectMemberIterator &rhs) const bool operator==(const PropertyTreeObjectMemberIterator &rhs) const
{ {
return itr == rhs.itr; return itr == rhs.itr;
} }
void increment() bool operator!=(const PropertyTreeObjectMemberIterator &rhs) const
{ {
itr++; return !(itr == rhs.itr);
} }
void decrement() const PropertyTreeObjectMemberIterator& operator++()
{
itr++;
return *this;
}
PropertyTreeObjectMemberIterator operator++(int)
{
PropertyTreeObjectMemberIterator iterator_pre(itr);
++(*this);
return iterator_pre;
}
const PropertyTreeObjectMemberIterator& operator--()
{ {
itr--; itr--;
return *this;
} }
private: private:

View File

@ -43,9 +43,7 @@
#define __VALIJSON_ADAPTERS_RAPIDJSON_ADAPTER_HPP #define __VALIJSON_ADAPTERS_RAPIDJSON_ADAPTER_HPP
#include <string> #include <string>
#include <boost/bind.hpp> #include <iterator>
#include <boost/optional.hpp>
#include <boost/iterator/iterator_facade.hpp>
#include <rapidjson/document.h> #include <rapidjson/document.h>
@ -403,18 +401,18 @@ public:
* @brief Optionally return a GenericRapidJsonArray instance. * @brief Optionally return a GenericRapidJsonArray instance.
* *
* If the referenced RapidJson value is an array, this function will return * If the referenced RapidJson value is an array, this function will return
* a boost::optional containing a GenericRapidJsonArray instance referencing * a std::optional containing a GenericRapidJsonArray instance referencing
* the array. * the array.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<GenericRapidJsonArray<ValueType> > getArrayOptional() const opt::optional<GenericRapidJsonArray<ValueType> > getArrayOptional() const
{ {
if (value.IsArray()) { if (value.IsArray()) {
return boost::make_optional(GenericRapidJsonArray<ValueType>(value)); return opt::make_optional(GenericRapidJsonArray<ValueType>(value));
} }
return boost::none; return opt::optional<GenericRapidJsonArray<ValueType> >();
} }
/** /**
@ -481,18 +479,18 @@ public:
* @brief Optionally return a GenericRapidJsonObject instance. * @brief Optionally return a GenericRapidJsonObject instance.
* *
* If the referenced RapidJson value is an object, this function will return * If the referenced RapidJson value is an object, this function will return
* a boost::optional containing a GenericRapidJsonObject instance * a std::optional containing a GenericRapidJsonObject instance
* referencing the object. * referencing the object.
* *
* Otherwise it will return boost::none. * Otherwise it will return an empty optional.
*/ */
boost::optional<GenericRapidJsonObject<ValueType> > getObjectOptional() const opt::optional<GenericRapidJsonObject<ValueType> > getObjectOptional() const
{ {
if (value.IsObject()) { if (value.IsObject()) {
return boost::make_optional(GenericRapidJsonObject<ValueType>(value)); return opt::make_optional(GenericRapidJsonObject<ValueType>(value));
} }
return boost::none; return opt::optional<GenericRapidJsonObject<ValueType> >();
} }
/** /**
@ -626,17 +624,15 @@ public:
* *
* This class provides a JSON array iterator that dereferences as an instance of * This class provides a JSON array iterator that dereferences as an instance of
* RapidJsonAdapter representing a value stored in the array. It has been * RapidJsonAdapter representing a value stored in the array. It has been
* implemented using the boost iterator_facade template. * implemented using the std::iterator template.
* *
* @see RapidJsonArray * @see RapidJsonArray
*/ */
template<class ValueType> template<class ValueType>
class GenericRapidJsonArrayValueIterator: class GenericRapidJsonArrayValueIterator:
public boost::iterator_facade< public std::iterator<
GenericRapidJsonArrayValueIterator<ValueType>, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
GenericRapidJsonAdapter<ValueType>, // value type GenericRapidJsonAdapter<ValueType> > // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
GenericRapidJsonAdapter<ValueType> > // type returned when dereferenced
{ {
public: public:
@ -652,11 +648,17 @@ public:
/// Returns a GenericRapidJsonAdapter that contains the value of the current /// Returns a GenericRapidJsonAdapter that contains the value of the current
/// element. /// element.
GenericRapidJsonAdapter<ValueType> dereference() const GenericRapidJsonAdapter<ValueType> operator*() const
{ {
return GenericRapidJsonAdapter<ValueType>(*itr); return GenericRapidJsonAdapter<ValueType>(*itr);
} }
/// Returns a proxy for the value of the current element
DerefProxy<GenericRapidJsonAdapter<ValueType> > operator->() const
{
return DerefProxy<GenericRapidJsonAdapter<ValueType> >(**this);
}
/** /**
* @brief Compare this iterator against another iterator. * @brief Compare this iterator against another iterator.
* *
@ -668,19 +670,34 @@ public:
* *
* @returns true if the iterators are equal, false otherwise. * @returns true if the iterators are equal, false otherwise.
*/ */
bool equal(const GenericRapidJsonArrayValueIterator &other) const bool operator==(const GenericRapidJsonArrayValueIterator<ValueType> &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const GenericRapidJsonArrayValueIterator<ValueType>& other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() GenericRapidJsonArrayValueIterator<ValueType>& operator++()
{
itr++;
return *this;
}
GenericRapidJsonArrayValueIterator<ValueType> operator++(int) {
GenericRapidJsonArrayValueIterator<ValueType> iterator_pre(itr);
++(*this);
return iterator_pre;
}
GenericRapidJsonArrayValueIterator<ValueType>& operator--()
{ {
itr--; itr--;
return *this;
} }
void advance(std::ptrdiff_t n) void advance(std::ptrdiff_t n)
@ -688,7 +705,7 @@ public:
itr += n; itr += n;
} }
std::ptrdiff_t difference(const GenericRapidJsonArrayValueIterator &other) std::ptrdiff_t difference(const GenericRapidJsonArrayValueIterator<ValueType> &other)
{ {
return std::distance(itr, other.itr); return std::distance(itr, other.itr);
} }
@ -703,18 +720,16 @@ private:
* *
* This class provides a JSON object iterator that dereferences as an instance * This class provides a JSON object iterator that dereferences as an instance
* of GenericRapidJsonObjectMember representing one of the members of the * of GenericRapidJsonObjectMember representing one of the members of the
* object. It has been implemented using the boost iterator_facade template. * object. It has been implemented using the std::iterator template.
* *
* @see GenericRapidJsonObject * @see GenericRapidJsonObject
* @see GenericRapidJsonObjectMember * @see GenericRapidJsonObjectMember
*/ */
template<class ValueType> template<class ValueType>
class GenericRapidJsonObjectMemberIterator: class GenericRapidJsonObjectMemberIterator:
public boost::iterator_facade< public std::iterator<
GenericRapidJsonObjectMemberIterator<ValueType>, // name of derived type std::bidirectional_iterator_tag, // bi-directional iterator
GenericRapidJsonObjectMember<ValueType>, // value type GenericRapidJsonObjectMember<ValueType> > // value type
boost::bidirectional_traversal_tag, // bi-directional iterator
GenericRapidJsonObjectMember<ValueType> > // type returned when dereferenced
{ {
public: public:
@ -727,17 +742,24 @@ public:
const typename ValueType::ConstMemberIterator &itr) const typename ValueType::ConstMemberIterator &itr)
: itr(itr) { } : itr(itr) { }
/** /**
* @brief Returns a GenericRapidJsonObjectMember that contains the key and * @brief Returns a GenericRapidJsonObjectMember that contains the key and
* value belonging to the object member identified by the iterator. * value belonging to the object member identified by the iterator.
*/ */
GenericRapidJsonObjectMember<ValueType> dereference() const GenericRapidJsonObjectMember<ValueType> operator*() const
{ {
return GenericRapidJsonObjectMember<ValueType>( return GenericRapidJsonObjectMember<ValueType>(
std::string(itr->name.GetString(), itr->name.GetStringLength()), std::string(itr->name.GetString(), itr->name.GetStringLength()),
itr->value); itr->value);
} }
/// Returns a proxy for the value of the current element
DerefProxy<GenericRapidJsonObjectMember<ValueType> > operator->() const
{
return DerefProxy<GenericRapidJsonObjectMember<ValueType> >(**this);
}
/** /**
* @brief Compare this iterator with another iterator. * @brief Compare this iterator with another iterator.
* *
@ -749,19 +771,35 @@ public:
* *
* @returns true if the underlying iterators are equal, false otherwise * @returns true if the underlying iterators are equal, false otherwise
*/ */
bool equal(const GenericRapidJsonObjectMemberIterator &other) const bool operator==(const GenericRapidJsonObjectMemberIterator<ValueType> &other) const
{ {
return itr == other.itr; return itr == other.itr;
} }
void increment() bool operator!=(const GenericRapidJsonObjectMemberIterator<ValueType> &other) const
{ {
itr++; return !(itr == other.itr);
} }
void decrement() GenericRapidJsonObjectMemberIterator<ValueType>& operator++()
{
itr++;
return *this;
}
GenericRapidJsonObjectMemberIterator<ValueType> operator++(int)
{
GenericRapidJsonObjectMemberIterator<ValueType> iterator_pre(itr);
++(*this);
return iterator_pre;
}
GenericRapidJsonObjectMemberIterator<ValueType>& operator--()
{ {
itr--; itr--;
return *this;
} }
std::ptrdiff_t difference(const GenericRapidJsonObjectMemberIterator &other) std::ptrdiff_t difference(const GenericRapidJsonObjectMemberIterator &other)

View File

@ -16,9 +16,6 @@
#ifndef __VALIJSON_CONSTRAINTS_CONCRETE_CONSTRAINTS_HPP #ifndef __VALIJSON_CONSTRAINTS_CONCRETE_CONSTRAINTS_HPP
#define __VALIJSON_CONSTRAINTS_CONCRETE_CONSTRAINTS_HPP #define __VALIJSON_CONSTRAINTS_CONCRETE_CONSTRAINTS_HPP
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/variant.hpp>
#include <limits> #include <limits>
#include <map> #include <map>
#include <set> #include <set>
@ -60,7 +57,7 @@ public:
void applyToSubschemas(const FunctorType &fn) const void applyToSubschemas(const FunctorType &fn) const
{ {
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const Subschema *subschema, subschemas ) { for (const Subschema *subschema : subschemas) {
if (!fn(index, subschema)) { if (!fn(index, subschema)) {
return; return;
} }
@ -103,7 +100,7 @@ public:
void applyToSubschemas(const FunctorType &fn) const void applyToSubschemas(const FunctorType &fn) const
{ {
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const Subschema *subschema, subschemas ) { for (const Subschema *subschema : subschemas) {
if (!fn(index, subschema)) { if (!fn(index, subschema)) {
return; return;
} }
@ -170,7 +167,7 @@ public:
} }
typedef typename ContainerType::value_type ValueType; typedef typename ContainerType::value_type ValueType;
BOOST_FOREACH( const ValueType &dependencyName, dependencyNames ) { for (const ValueType &dependencyName : dependencyNames) {
itr->second.insert(String(dependencyName.c_str(), allocator)); itr->second.insert(String(dependencyName.c_str(), allocator));
} }
@ -196,8 +193,7 @@ public:
template<typename FunctorType> template<typename FunctorType>
void applyToPropertyDependencies(const FunctorType &fn) const void applyToPropertyDependencies(const FunctorType &fn) const
{ {
BOOST_FOREACH( const PropertyDependencies::value_type &v, for (const PropertyDependencies::value_type &v : propertyDependencies) {
propertyDependencies ) {
if (!fn(v.first, v.second)) { if (!fn(v.first, v.second)) {
return; return;
} }
@ -207,8 +203,7 @@ public:
template<typename FunctorType> template<typename FunctorType>
void applyToSchemaDependencies(const FunctorType &fn) const void applyToSchemaDependencies(const FunctorType &fn) const
{ {
BOOST_FOREACH( const SchemaDependencies::value_type &v, for (const SchemaDependencies::value_type &v : schemaDependencies) {
schemaDependencies ) {
if (!fn(v.first, v.second)) { if (!fn(v.first, v.second)) {
return; return;
} }
@ -254,7 +249,7 @@ public:
{ {
try { try {
// Clone individual enum values // Clone individual enum values
BOOST_FOREACH( const EnumValue *otherValue, other.enumValues ) { for (const EnumValue *otherValue : other.enumValues) {
const EnumValue *value = otherValue->clone(); const EnumValue *value = otherValue->clone();
try { try {
enumValues.push_back(value); enumValues.push_back(value);
@ -266,7 +261,7 @@ public:
} catch (...) { } catch (...) {
// Delete values already added to constraint // Delete values already added to constraint
BOOST_FOREACH( const EnumValue *value, enumValues ) { for (const EnumValue *value : enumValues) {
delete value; delete value;
} }
throw; throw;
@ -275,7 +270,7 @@ public:
virtual ~EnumConstraint() virtual ~EnumConstraint()
{ {
BOOST_FOREACH( const EnumValue *value, enumValues ) { for (const EnumValue *value : enumValues) {
delete value; delete value;
} }
} }
@ -295,7 +290,7 @@ public:
template<typename FunctorType> template<typename FunctorType>
void applyToValues(const FunctorType &fn) const void applyToValues(const FunctorType &fn) const
{ {
BOOST_FOREACH( const EnumValue *value, enumValues ) { for (const EnumValue *value : enumValues) {
if (!fn(*value)) { if (!fn(*value)) {
return; return;
} }
@ -345,7 +340,7 @@ public:
void applyToItemSubschemas(const FunctorType &fn) const void applyToItemSubschemas(const FunctorType &fn) const
{ {
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const Subschema *subschema, itemSubschemas ) { for( const Subschema *subschema : itemSubschemas ) {
if (!fn(index, subschema)) { if (!fn(index, subschema)) {
return; return;
} }
@ -727,7 +722,7 @@ public:
void applyToSubschemas(const FunctorType &fn) const void applyToSubschemas(const FunctorType &fn) const
{ {
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const Subschema *subschema, subschemas ) { for( const Subschema *subschema : subschemas ) {
if (!fn(index, subschema)) { if (!fn(index, subschema)) {
return; return;
} }
@ -870,7 +865,7 @@ public:
void applyToPatternProperties(const FunctorType &fn) const void applyToPatternProperties(const FunctorType &fn) const
{ {
typedef typename PropertySchemaMap::value_type ValueType; typedef typename PropertySchemaMap::value_type ValueType;
BOOST_FOREACH( const ValueType &value, patternProperties ) { for( const ValueType &value : patternProperties ) {
if (!fn(value.first, value.second)) { if (!fn(value.first, value.second)) {
return; return;
} }
@ -881,7 +876,7 @@ public:
void applyToProperties(const FunctorType &fn) const void applyToProperties(const FunctorType &fn) const
{ {
typedef typename PropertySchemaMap::value_type ValueType; typedef typename PropertySchemaMap::value_type ValueType;
BOOST_FOREACH( const ValueType &value, properties ) { for( const ValueType &value : properties ) {
if (!fn(value.first, value.second)) { if (!fn(value.first, value.second)) {
return; return;
} }
@ -937,7 +932,7 @@ public:
template<typename FunctorType> template<typename FunctorType>
void applyToRequiredProperties(const FunctorType &fn) const void applyToRequiredProperties(const FunctorType &fn) const
{ {
BOOST_FOREACH( const String &propertyName, requiredProperties ) { for( const String &propertyName : requiredProperties ) {
if (!fn(propertyName)) { if (!fn(propertyName)) {
return; return;
} }
@ -1024,7 +1019,7 @@ public:
template<typename FunctorType> template<typename FunctorType>
void applyToNamedTypes(const FunctorType &fn) const void applyToNamedTypes(const FunctorType &fn) const
{ {
BOOST_FOREACH( const JsonType namedType, namedTypes ) { for( const JsonType namedType : namedTypes ) {
if (!fn(namedType)) { if (!fn(namedType)) {
return; return;
} }
@ -1035,7 +1030,7 @@ public:
void applyToSchemaTypes(const FunctorType &fn) const void applyToSchemaTypes(const FunctorType &fn) const
{ {
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const Subschema *subschema, schemaTypes ) { for( const Subschema *subschema : schemaTypes ) {
if (!fn(index, subschema)) { if (!fn(index, subschema)) {
return; return;
} }

View File

@ -2,13 +2,19 @@
#ifndef __VALIJSON_INTERNAL_JSON_POINTER_HPP #ifndef __VALIJSON_INTERNAL_JSON_POINTER_HPP
#define __VALIJSON_INTERNAL_JSON_POINTER_HPP #define __VALIJSON_INTERNAL_JSON_POINTER_HPP
#include <algorithm>
#include <cerrno> #include <cerrno>
#include <cstddef>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <boost/algorithm/string/replace.hpp> #if __has_include(<optional>)
#include <boost/lexical_cast.hpp> # include <optional>
#include <boost/optional.hpp> namespace opt = std;
#else
# include <compat/optional.hpp>
namespace opt = std::experimental;
#endif
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
@ -16,6 +22,24 @@ namespace valijson {
namespace internal { namespace internal {
namespace json_pointer { namespace json_pointer {
/**
* @brief Replace all occurrences of `search` with `replace`. Modifies `subject` in place
*
* @param subject string to operate on
* @param search string to search
* @param replace replacement string
*/
inline void replace_all_inplace(std::string& subject, const char* search,
const char* replace)
{
size_t pos = 0;
while((pos = subject.find(search, pos)) != std::string::npos) {
subject.replace(pos, strlen(search), replace);
pos += strlen(replace);
}
}
/** /**
* @brief Return the char value corresponding to a 2-digit hexadecimal string * @brief Return the char value corresponding to a 2-digit hexadecimal string
* *
@ -78,8 +102,8 @@ inline std::string extractReferenceToken(std::string::const_iterator begin,
std::string token(begin, end); std::string token(begin, end);
// Replace JSON Pointer-specific escaped character sequences // Replace JSON Pointer-specific escaped character sequences
boost::replace_all(token, "~1", "/"); replace_all_inplace(token, "~1", "/");
boost::replace_all(token, "~0", "~"); replace_all_inplace(token, "~0", "~");
// Replace %-encoded character sequences with their actual characters // Replace %-encoded character sequences with their actual characters
for (size_t n = token.find('%'); n != std::string::npos; for (size_t n = token.find('%'); n != std::string::npos;
@ -169,8 +193,7 @@ inline AdapterType resolveJsonPointer(
try { try {
// Fragment must be non-negative integer // Fragment must be non-negative integer
const uint64_t index = boost::lexical_cast<uint64_t>( const uint64_t index = std::stoul(referenceToken);
referenceToken);
typedef typename AdapterType::Array Array; typedef typename AdapterType::Array Array;
typename Array::const_iterator itr = node.asArray().begin(); typename Array::const_iterator itr = node.asArray().begin();
@ -180,18 +203,18 @@ inline AdapterType resolveJsonPointer(
"out of bounds; actual token: " + referenceToken); "out of bounds; actual token: " + referenceToken);
} }
if (index > static_cast<uint64_t>(std::numeric_limits<ptrdiff_t>::max())) { if (index > static_cast<uint64_t>(std::numeric_limits<std::ptrdiff_t>::max())) {
throw std::runtime_error("Array index out of bounds; hard " throw std::runtime_error("Array index out of bounds; hard "
"limit is " + boost::lexical_cast<std::string>( "limit is " + std::to_string(
std::numeric_limits<ptrdiff_t>::max())); std::numeric_limits<std::ptrdiff_t>::max()));
} }
itr.advance(static_cast<ptrdiff_t>(index)); itr.advance(static_cast<std::ptrdiff_t>(index));
// Recursively process the remaining tokens // Recursively process the remaining tokens
return resolveJsonPointer(*itr, jsonPointer, jsonPointerNext); return resolveJsonPointer(*itr, jsonPointer, jsonPointerNext);
} catch (boost::bad_lexical_cast &) { } catch (std::invalid_argument &) {
throw std::runtime_error("Expected reference token to contain a " throw std::runtime_error("Expected reference token to contain a "
"non-negative integer to identify an element in the " "non-negative integer to identify an element in the "
"current array; actual token: " + referenceToken); "current array; actual token: " + referenceToken);

View File

@ -5,7 +5,13 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <boost/optional.hpp> #if __has_include(<optional>)
# include <optional>
namespace opt = std;
#else
# include <compat/optional.hpp>
namespace opt = std::experimental;
#endif
namespace valijson { namespace valijson {
namespace internal { namespace internal {
@ -19,14 +25,14 @@ namespace json_reference {
* *
* @return Optional string containing URI * @return Optional string containing URI
*/ */
inline boost::optional<std::string> getJsonReferenceUri( inline opt::optional<std::string> getJsonReferenceUri(
const std::string &jsonRef) const std::string &jsonRef)
{ {
const size_t ptrPos = jsonRef.find("#"); const size_t ptrPos = jsonRef.find("#");
if (ptrPos == 0) { if (ptrPos == 0) {
// The JSON Reference does not contain a URI, but might contain a // The JSON Reference does not contain a URI, but might contain a
// JSON Pointer that refers to the current document // JSON Pointer that refers to the current document
return boost::none; return opt::optional<std::string>();
} else if (ptrPos != std::string::npos) { } else if (ptrPos != std::string::npos) {
// The JSON Reference contains a URI and possibly a JSON Pointer // The JSON Reference contains a URI and possibly a JSON Pointer
return jsonRef.substr(0, ptrPos); return jsonRef.substr(0, ptrPos);
@ -43,7 +49,7 @@ namespace json_reference {
* *
* @return Optional string containing JSON Pointer * @return Optional string containing JSON Pointer
*/ */
inline boost::optional<std::string> getJsonReferencePointer( inline opt::optional<std::string> getJsonReferencePointer(
const std::string &jsonRef) const std::string &jsonRef)
{ {
// Attempt to extract JSON Pointer if '#' character is present. Note // Attempt to extract JSON Pointer if '#' character is present. Note
@ -54,7 +60,7 @@ namespace json_reference {
return jsonRef.substr(ptrPos + 1); return jsonRef.substr(ptrPos + 1);
} }
return boost::none; return opt::optional<std::string>();
} }

View File

@ -7,11 +7,6 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <valijson/adapters/adapter.hpp> #include <valijson/adapters/adapter.hpp>
#include <valijson/constraints/concrete_constraints.hpp> #include <valijson/constraints/concrete_constraints.hpp>
#include <valijson/internal/json_pointer.hpp> #include <valijson/internal/json_pointer.hpp>
@ -135,7 +130,8 @@ public:
typename DocumentCache<AdapterType>::Type docCache; typename DocumentCache<AdapterType>::Type docCache;
SchemaCache schemaCache; SchemaCache schemaCache;
try { try {
resolveThenPopulateSchema(schema, node, node, schema, boost::none, "", resolveThenPopulateSchema(schema, node, node, schema,
opt::optional<std::string>(), "",
fetchDoc, NULL, NULL, docCache, schemaCache); fetchDoc, NULL, NULL, docCache, schemaCache);
} catch (...) { } catch (...) {
freeDocumentCache<AdapterType>(docCache, freeDoc); freeDocumentCache<AdapterType>(docCache, freeDoc);
@ -178,7 +174,7 @@ private:
{ {
typedef typename DocumentCache<AdapterType>::Type DocCacheType; typedef typename DocumentCache<AdapterType>::Type DocCacheType;
BOOST_FOREACH( const typename DocCacheType::value_type &v, docCache ) { for (const typename DocCacheType::value_type &v : docCache) {
freeDoc(v.second); freeDoc(v.second);
} }
} }
@ -207,9 +203,9 @@ private:
* document URI should be used to replace the path, query and fragment * document URI should be used to replace the path, query and fragment
* portions of URI provided by the resolution scope. * portions of URI provided by the resolution scope.
*/ */
static boost::optional<std::string> findAbsoluteDocumentUri( static opt::optional<std::string> findAbsoluteDocumentUri(
const boost::optional<std::string> resolutionScope, const opt::optional<std::string> resolutionScope,
const boost::optional<std::string> documentUri) const opt::optional<std::string> documentUri)
{ {
if (resolutionScope) { if (resolutionScope) {
if (documentUri) { if (documentUri) {
@ -225,7 +221,7 @@ private:
} else if (documentUri && internal::uri::isUriAbsolute(*documentUri)) { } else if (documentUri && internal::uri::isUriAbsolute(*documentUri)) {
return *documentUri; return *documentUri;
} else { } else {
return boost::none; return opt::optional<std::string>();
} }
} }
@ -262,7 +258,7 @@ private:
/** /**
* Sanitise an optional JSON Pointer, trimming trailing slashes * Sanitise an optional JSON Pointer, trimming trailing slashes
*/ */
std::string sanitiseJsonPointer(const boost::optional<std::string> input) std::string sanitiseJsonPointer(const opt::optional<std::string> input)
{ {
if (input) { if (input) {
// Trim trailing slash(es) // Trim trailing slash(es)
@ -318,7 +314,7 @@ private:
const std::vector<std::string> &keysToCreate, const std::vector<std::string> &keysToCreate,
const Subschema *schema) const Subschema *schema)
{ {
BOOST_FOREACH( const std::string &keyToCreate, keysToCreate ) { for (const std::string &keyToCreate : keysToCreate) {
const SchemaCache::value_type value(keyToCreate, schema); const SchemaCache::value_type value(keyToCreate, schema);
if (!schemaCache.insert(value).second) { if (!schemaCache.insert(value).second) {
throw std::logic_error( throw std::logic_error(
@ -363,7 +359,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
const Subschema *parentSubschema, const Subschema *parentSubschema,
@ -408,7 +404,7 @@ private:
// Returns a document URI if the reference points somewhere // Returns a document URI if the reference points somewhere
// other than the current document // other than the current document
const boost::optional<std::string> documentUri = const opt::optional<std::string> documentUri =
internal::json_reference::getJsonReferenceUri(jsonRef); internal::json_reference::getJsonReferenceUri(jsonRef);
// Extract JSON Pointer from JSON Reference, with any trailing // Extract JSON Pointer from JSON Reference, with any trailing
@ -421,7 +417,7 @@ private:
// scope. An absolute document URI will take precedence when // scope. An absolute document URI will take precedence when
// present, otherwise we need to resolve the URI relative to // present, otherwise we need to resolve the URI relative to
// the current resolution scope // the current resolution scope
const boost::optional<std::string> actualDocumentUri = const opt::optional<std::string> actualDocumentUri =
findAbsoluteDocumentUri(currentScope, documentUri); findAbsoluteDocumentUri(currentScope, documentUri);
// Construct a key to search the schema cache for an existing schema // Construct a key to search the schema cache for an existing schema
@ -536,7 +532,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
const Subschema *parentSubschema, const Subschema *parentSubschema,
@ -583,7 +579,7 @@ private:
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const Subschema &subschema, const Subschema &subschema,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
const Subschema *parentSubschema, const Subschema *parentSubschema,
@ -591,7 +587,7 @@ private:
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
SchemaCache &schemaCache) SchemaCache &schemaCache)
{ {
BOOST_STATIC_ASSERT_MSG((boost::is_convertible<AdapterType, static_assert((std::is_convertible<AdapterType,
const valijson::adapters::Adapter &>::value), const valijson::adapters::Adapter &>::value),
"SchemaParser::populateSchema must be invoked with an " "SchemaParser::populateSchema must be invoked with an "
"appropriate Adapter implementation"); "appropriate Adapter implementation");
@ -600,7 +596,7 @@ private:
typename AdapterType::Object::const_iterator itr(object.end()); typename AdapterType::Object::const_iterator itr(object.end());
// Check for 'id' attribute and update current scope // Check for 'id' attribute and update current scope
boost::optional<std::string> updatedScope; opt::optional<std::string> updatedScope;
if ((itr = object.find("id")) != object.end() && if ((itr = object.find("id")) != object.end() &&
itr->second.maybeString()) { itr->second.maybeString()) {
const std::string id = itr->second.asString(); const std::string id = itr->second.asString();
@ -841,7 +837,7 @@ private:
if ((itr = object.find("required")) != object.end()) { if ((itr = object.find("required")) != object.end()) {
if (version == kDraft3) { if (version == kDraft3) {
if (parentSubschema && ownName) { if (parentSubschema && ownName) {
boost::optional<constraints::RequiredConstraint> opt::optional<constraints::RequiredConstraint>
constraint = makeRequiredConstraintForSelf( constraint = makeRequiredConstraintForSelf(
itr->second, *ownName); itr->second, *ownName);
if (constraint) { if (constraint) {
@ -877,7 +873,7 @@ private:
} }
if ((itr = object.find("uniqueItems")) != object.end()) { if ((itr = object.find("uniqueItems")) != object.end()) {
boost::optional<constraints::UniqueItemsConstraint> constraint = opt::optional<constraints::UniqueItemsConstraint> constraint =
makeUniqueItemsConstraint(itr->second); makeUniqueItemsConstraint(itr->second);
if (constraint) { if (constraint) {
rootSchema.addConstraintToSubschema(*constraint, &subschema); rootSchema.addConstraintToSubschema(*constraint, &subschema);
@ -933,7 +929,7 @@ private:
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const Subschema &subschema, const Subschema &subschema,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
const Subschema *parentSchema, const Subschema *parentSchema,
@ -951,7 +947,7 @@ private:
// Returns a document URI if the reference points somewhere // Returns a document URI if the reference points somewhere
// other than the current document // other than the current document
const boost::optional<std::string> documentUri = const opt::optional<std::string> documentUri =
internal::json_reference::getJsonReferenceUri(jsonRef); internal::json_reference::getJsonReferenceUri(jsonRef);
// Extract JSON Pointer from JSON Reference // Extract JSON Pointer from JSON Reference
@ -989,7 +985,7 @@ private:
// TODO: Need to detect degenerate circular references // TODO: Need to detect degenerate circular references
resolveThenPopulateSchema(rootSchema, newRootNode, resolveThenPopulateSchema(rootSchema, newRootNode,
referencedAdapter, subschema, boost::none, referencedAdapter, subschema, opt::optional<std::string>(),
actualJsonPointer, fetchDoc, parentSchema, ownName, actualJsonPointer, fetchDoc, parentSchema, ownName,
docCache, schemaCache); docCache, schemaCache);
@ -1000,7 +996,8 @@ private:
// TODO: Need to detect degenerate circular references // TODO: Need to detect degenerate circular references
resolveThenPopulateSchema(rootSchema, rootNode, referencedAdapter, resolveThenPopulateSchema(rootSchema, rootNode, referencedAdapter,
subschema, boost::none, actualJsonPointer, fetchDoc, subschema, opt::optional<std::string>(),
actualJsonPointer, fetchDoc,
parentSchema, ownName, docCache, schemaCache); parentSchema, ownName, docCache, schemaCache);
} }
} }
@ -1028,7 +1025,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1042,10 +1039,10 @@ private:
constraints::AllOfConstraint constraint; constraints::AllOfConstraint constraint;
int index = 0; int index = 0;
BOOST_FOREACH ( const AdapterType schemaNode, node.asArray() ) { for ( const AdapterType schemaNode : node.asArray() ) {
if (schemaNode.maybeObject()) { if (schemaNode.maybeObject()) {
const std::string childPath = nodePath + "/" + const std::string childPath = nodePath + "/" +
boost::lexical_cast<std::string>(index); std::to_string(index);
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
rootSchema, rootNode, schemaNode, currentScope, rootSchema, rootNode, schemaNode, currentScope,
childPath, fetchDoc, NULL, NULL, docCache, schemaCache); childPath, fetchDoc, NULL, NULL, docCache, schemaCache);
@ -1084,7 +1081,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1098,10 +1095,10 @@ private:
constraints::AnyOfConstraint constraint; constraints::AnyOfConstraint constraint;
int index = 0; int index = 0;
BOOST_FOREACH ( const AdapterType schemaNode, node.asArray() ) { for ( const AdapterType schemaNode : node.asArray() ) {
if (schemaNode.maybeObject()) { if (schemaNode.maybeObject()) {
const std::string childPath = nodePath + "/" + const std::string childPath = nodePath + "/" +
boost::lexical_cast<std::string>(index); std::to_string(index);
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
rootSchema, rootNode, schemaNode, currentScope, rootSchema, rootNode, schemaNode, currentScope,
childPath, fetchDoc, NULL, NULL, docCache, schemaCache); childPath, fetchDoc, NULL, NULL, docCache, schemaCache);
@ -1158,7 +1155,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1171,7 +1168,7 @@ private:
constraints::DependenciesConstraint dependenciesConstraint; constraints::DependenciesConstraint dependenciesConstraint;
// Process each of the dependency mappings defined by the object // Process each of the dependency mappings defined by the object
BOOST_FOREACH ( const typename AdapterType::ObjectMember member, node.asObject() ) { for ( const typename AdapterType::ObjectMember member : node.asObject() ) {
// First, we attempt to parse the value of the dependency mapping // First, we attempt to parse the value of the dependency mapping
// as an array of strings. If the Adapter type does not support // as an array of strings. If the Adapter type does not support
@ -1183,7 +1180,7 @@ private:
if (member.second.maybeArray()) { if (member.second.maybeArray()) {
// Parse an array of dependency names // Parse an array of dependency names
std::vector<std::string> dependentPropertyNames; std::vector<std::string> dependentPropertyNames;
BOOST_FOREACH( const AdapterType dependencyName, member.second.asArray() ) { for (const AdapterType dependencyName : member.second.asArray()) {
if (dependencyName.maybeString()) { if (dependencyName.maybeString()) {
dependentPropertyNames.push_back(dependencyName.getString()); dependentPropertyNames.push_back(dependencyName.getString());
} else { } else {
@ -1240,7 +1237,7 @@ private:
{ {
// Make a copy of each value in the enum array // Make a copy of each value in the enum array
constraints::EnumConstraint constraint; constraints::EnumConstraint constraint;
BOOST_FOREACH( const AdapterType value, node.getArray() ) { for (const AdapterType value : node.getArray()) {
constraint.addValue(value); constraint.addValue(value);
} }
@ -1286,7 +1283,7 @@ private:
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType *items, const AdapterType *items,
const AdapterType *additionalItems, const AdapterType *additionalItems,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &itemsPath, const std::string &itemsPath,
const std::string &additionalItemsPath, const std::string &additionalItemsPath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
@ -1338,9 +1335,9 @@ private:
// validate the values at the corresponding indexes in a target // validate the values at the corresponding indexes in a target
// array. // array.
int index = 0; int index = 0;
BOOST_FOREACH( const AdapterType v, items->getArray() ) { for (const AdapterType v : items->getArray()) {
const std::string childPath = itemsPath + "/" + const std::string childPath = itemsPath + "/" +
boost::lexical_cast<std::string>(index); std::to_string(index);
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
rootSchema, rootNode, v, currentScope, childPath, rootSchema, rootNode, v, currentScope, childPath,
fetchDoc, NULL, NULL, docCache, schemaCache); fetchDoc, NULL, NULL, docCache, schemaCache);
@ -1391,7 +1388,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &items, const AdapterType &items,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &itemsPath, const std::string &itemsPath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1726,7 +1723,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1766,7 +1763,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -1775,9 +1772,9 @@ private:
constraints::OneOfConstraint constraint; constraints::OneOfConstraint constraint;
int index = 0; int index = 0;
BOOST_FOREACH ( const AdapterType schemaNode, node.getArray() ) { for ( const AdapterType schemaNode : node.getArray() ) {
const std::string childPath = nodePath + "/" + const std::string childPath = nodePath + "/" +
boost::lexical_cast<std::string>(index); std::to_string(index);
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
rootSchema, rootNode, schemaNode, currentScope, childPath, rootSchema, rootNode, schemaNode, currentScope, childPath,
fetchDoc, NULL, NULL, docCache, schemaCache); fetchDoc, NULL, NULL, docCache, schemaCache);
@ -1849,7 +1846,7 @@ private:
const AdapterType *properties, const AdapterType *properties,
const AdapterType *patternProperties, const AdapterType *patternProperties,
const AdapterType *additionalProperties, const AdapterType *additionalProperties,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &propertiesPath, const std::string &propertiesPath,
const std::string &patternPropertiesPath, const std::string &patternPropertiesPath,
const std::string &additionalPropertiesPath, const std::string &additionalPropertiesPath,
@ -1864,7 +1861,7 @@ private:
// Create subschemas for 'properties' constraint // Create subschemas for 'properties' constraint
if (properties) { if (properties) {
BOOST_FOREACH( const Member m, properties->getObject() ) { for (const Member m : properties->getObject()) {
const std::string &property = m.first; const std::string &property = m.first;
const std::string childPath = propertiesPath + "/" + property; const std::string childPath = propertiesPath + "/" + property;
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
@ -1877,7 +1874,7 @@ private:
// Create subschemas for 'patternProperties' constraint // Create subschemas for 'patternProperties' constraint
if (patternProperties) { if (patternProperties) {
BOOST_FOREACH( const Member m, patternProperties->getObject() ) { for (const Member m : patternProperties->getObject()) {
const std::string &pattern = m.first; const std::string &pattern = m.first;
const std::string childPath = patternPropertiesPath + "/" + const std::string childPath = patternPropertiesPath + "/" +
pattern; pattern;
@ -1942,7 +1939,7 @@ private:
* caller * caller
*/ */
template<typename AdapterType> template<typename AdapterType>
boost::optional<constraints::RequiredConstraint> opt::optional<constraints::RequiredConstraint>
makeRequiredConstraintForSelf(const AdapterType &node, makeRequiredConstraintForSelf(const AdapterType &node,
const std::string &name) const std::string &name)
{ {
@ -1956,7 +1953,7 @@ private:
return constraint; return constraint;
} }
return boost::none; return opt::optional<constraints::RequiredConstraint>();
} }
/** /**
@ -1976,7 +1973,7 @@ private:
{ {
constraints::RequiredConstraint constraint; constraints::RequiredConstraint constraint;
BOOST_FOREACH( const AdapterType v, node.getArray() ) { for (const AdapterType v : node.getArray()) {
if (!v.isString()) { if (!v.isString()) {
throw std::runtime_error("Expected required property name to " throw std::runtime_error("Expected required property name to "
"be a string value"); "be a string value");
@ -2010,7 +2007,7 @@ private:
Schema &rootSchema, Schema &rootSchema,
const AdapterType &rootNode, const AdapterType &rootNode,
const AdapterType &node, const AdapterType &node,
const boost::optional<std::string> currentScope, const opt::optional<std::string> currentScope,
const std::string &nodePath, const std::string &nodePath,
const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc, const typename FunctionPtrs<AdapterType>::FetchDoc fetchDoc,
typename DocumentCache<AdapterType>::Type &docCache, typename DocumentCache<AdapterType>::Type &docCache,
@ -2033,7 +2030,7 @@ private:
} else if (node.isArray()) { } else if (node.isArray()) {
int index = 0; int index = 0;
BOOST_FOREACH( const AdapterType v, node.getArray() ) { for (const AdapterType v : node.getArray()) {
if (v.isString()) { if (v.isString()) {
const TypeConstraint::JsonType type = const TypeConstraint::JsonType type =
TypeConstraint::jsonTypeFromString(v.getString()); TypeConstraint::jsonTypeFromString(v.getString());
@ -2048,7 +2045,7 @@ private:
} else if (v.isObject() && version == kDraft3) { } else if (v.isObject() && version == kDraft3) {
const std::string childPath = nodePath + "/" + const std::string childPath = nodePath + "/" +
boost::lexical_cast<std::string>(index); std::to_string(index);
const Subschema *subschema = makeOrReuseSchema<AdapterType>( const Subschema *subschema = makeOrReuseSchema<AdapterType>(
rootSchema, rootNode, v, currentScope, childPath, rootSchema, rootNode, v, currentScope, childPath,
fetchDoc, NULL, NULL, docCache, schemaCache); fetchDoc, NULL, NULL, docCache, schemaCache);
@ -2083,7 +2080,7 @@ private:
* the caller, or NULL if the boolean value is false. * the caller, or NULL if the boolean value is false.
*/ */
template<typename AdapterType> template<typename AdapterType>
boost::optional<constraints::UniqueItemsConstraint> opt::optional<constraints::UniqueItemsConstraint>
makeUniqueItemsConstraint(const AdapterType &node) makeUniqueItemsConstraint(const AdapterType &node)
{ {
if (node.isBool() || node.maybeBool()) { if (node.isBool() || node.maybeBool()) {
@ -2093,7 +2090,7 @@ private:
if (node.asBool()) { if (node.asBool()) {
return constraints::UniqueItemsConstraint(); return constraints::UniqueItemsConstraint();
} else { } else {
return boost::none; return opt::optional<constraints::UniqueItemsConstraint>();
} }
} }

View File

@ -4,11 +4,17 @@
#include <vector> #include <vector>
#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/optional.hpp>
#include <memory> #include <memory>
// This should be removed once C++17 is widely available
#if __has_include(<optional>)
# include <optional>
namespace opt = std;
#else
# include <compat/optional.hpp>
namespace opt = std::experimental;
#endif
#include <valijson/constraints/constraint.hpp> #include <valijson/constraints/constraint.hpp>
namespace valijson { namespace valijson {
@ -37,7 +43,7 @@ public:
/// Typedef for a function that can be applied to each of the Constraint /// Typedef for a function that can be applied to each of the Constraint
/// instances owned by a Schema. /// instances owned by a Schema.
typedef boost::function<bool (const Constraint &)> ApplyFunction; typedef std::function<bool (const Constraint &)> ApplyFunction;
/** /**
* @brief Construct a new Subschema object * @brief Construct a new Subschema object
@ -115,7 +121,7 @@ public:
bool apply(ApplyFunction &applyFunction) const bool apply(ApplyFunction &applyFunction) const
{ {
bool allTrue = true; bool allTrue = true;
BOOST_FOREACH( const Constraint *constraint, constraints ) { for (const Constraint *constraint : constraints) {
allTrue = allTrue && applyFunction(*constraint); allTrue = allTrue && applyFunction(*constraint);
} }
@ -134,7 +140,7 @@ public:
*/ */
bool applyStrict(ApplyFunction &applyFunction) const bool applyStrict(ApplyFunction &applyFunction) const
{ {
BOOST_FOREACH( const Constraint *constraint, constraints ) { for (const Constraint *constraint : constraints) {
if (!applyFunction(*constraint)) { if (!applyFunction(*constraint)) {
return false; return false;
} }
@ -198,7 +204,7 @@ public:
*/ */
bool hasDescription() const bool hasDescription() const
{ {
return description != boost::none; return static_cast<bool>(description);
} }
/** /**
@ -208,7 +214,7 @@ public:
*/ */
bool hasId() const bool hasId() const
{ {
return id != boost::none; return static_cast<bool>(id);
} }
/** /**
@ -218,7 +224,7 @@ public:
*/ */
bool hasTitle() const bool hasTitle() const
{ {
return title != boost::none; return static_cast<bool>(title);
} }
/** /**
@ -274,13 +280,13 @@ private:
std::vector<const Constraint *> constraints; std::vector<const Constraint *> constraints;
/// Schema description (optional) /// Schema description (optional)
boost::optional<std::string> description; opt::optional<std::string> description;
/// Id to apply when resolving the schema URI /// Id to apply when resolving the schema URI
boost::optional<std::string> id; opt::optional<std::string> id;
/// Title string associated with the schema (optional) /// Title string associated with the schema (optional)
boost::optional<std::string> title; opt::optional<std::string> title;
}; };
} // namespace valijson } // namespace valijson

View File

@ -3,6 +3,7 @@
#define __VALIJSON_FILE_UTILS_HPP #define __VALIJSON_FILE_UTILS_HPP
#include <fstream> #include <fstream>
#include <limits>
namespace valijson { namespace valijson {
namespace utils { namespace utils {

View File

@ -16,8 +16,6 @@
# include <boost/property_tree/json_parser.hpp> # include <boost/property_tree/json_parser.hpp>
#endif #endif
#include <boost/property_tree/detail/json_parser_error.hpp>
#include <valijson/utils/file_utils.hpp> #include <valijson/utils/file_utils.hpp>
namespace valijson { namespace valijson {
@ -27,7 +25,7 @@ inline bool loadDocument(const std::string &path, boost::property_tree::ptree &d
{ {
try { try {
boost::property_tree::read_json(path, document); boost::property_tree::read_json(path, document);
} catch (boost::property_tree::json_parser::json_parser_error &e) { } catch (std::exception &e) {
std::cerr << "Boost Property Tree JSON parser failed to parse the document:" << std::endl; std::cerr << "Boost Property Tree JSON parser failed to parse the document:" << std::endl;
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
return false; return false;

View File

@ -50,7 +50,7 @@ inline uint64_t u8_strlen(const char *s)
if (i == maxLength) { if (i == maxLength) {
throw std::runtime_error( throw std::runtime_error(
"String exceeded maximum size of " + "String exceeded maximum size of " +
boost::lexical_cast<std::string>(maxLength) + " bytes."); std::to_string(maxLength) + " bytes.");
} }
count++; count++;
} }

View File

@ -3,10 +3,8 @@
#define __VALIJSON_VALIDATION_VISITOR_HPP #define __VALIJSON_VALIDATION_VISITOR_HPP
#include <cmath> #include <cmath>
#include <string>
#include <boost/lexical_cast.hpp> #include <regex>
#include <boost/regex.hpp>
#include <boost/variant/get.hpp>
#include <valijson/constraints/concrete_constraints.hpp> #include <valijson/constraints/concrete_constraints.hpp>
#include <valijson/constraints/constraint_visitor.hpp> #include <valijson/constraints/constraint_visitor.hpp>
@ -70,7 +68,7 @@ public:
// Wrap the validationCallback() function below so that it will be // Wrap the validationCallback() function below so that it will be
// passed a reference to a constraint (_1), and a reference to the // passed a reference to a constraint (_1), and a reference to the
// visitor (*this). // visitor (*this).
Subschema::ApplyFunction fn(boost::bind(validationCallback, _1, *this)); Subschema::ApplyFunction fn(std::bind(validationCallback, std::placeholders::_1, *this));
// Perform validation against each constraint defined in the schema // Perform validation against each constraint defined in the schema
if (results == NULL) { if (results == NULL) {
@ -308,7 +306,7 @@ public:
// Update context for current array item // Update context for current array item
std::vector<std::string> newContext = context; std::vector<std::string> newContext = context;
newContext.push_back("[" + newContext.push_back("[" +
boost::lexical_cast<std::string>(index) + "]"); std::to_string(index) + "]");
ValidationVisitor<AdapterType> validator(*itr, newContext, ValidationVisitor<AdapterType> validator(*itr, newContext,
strictTypes, results); strictTypes, results);
@ -317,7 +315,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Failed to validate item #" + "Failed to validate item #" +
boost::lexical_cast<std::string>(index) + std::to_string(index) +
" against additional items schema."); " against additional items schema.");
validated = false; validated = false;
} else { } else {
@ -330,7 +328,7 @@ public:
} else if (results) { } else if (results) {
results->pushError(context, "Cannot validate item #" + results->pushError(context, "Cannot validate item #" +
boost::lexical_cast<std::string>(numValidated) + " or " std::to_string(numValidated) + " or "
"greater using 'items' constraint or 'additionalItems' " "greater using 'items' constraint or 'additionalItems' "
"constraint."); "constraint.");
validated = false; validated = false;
@ -363,7 +361,7 @@ public:
if (target.asDouble() >= maximum) { if (target.asDouble() >= maximum) {
if (results) { if (results) {
results->pushError(context, "Expected number less than " + results->pushError(context, "Expected number less than " +
boost::lexical_cast<std::string>(maximum)); std::to_string(maximum));
} }
return false; return false;
@ -373,7 +371,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Expected number less than or equal to " + "Expected number less than or equal to " +
boost::lexical_cast<std::string>(maximum)); std::to_string(maximum));
} }
return false; return false;
@ -402,7 +400,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Array should contain no more than " + results->pushError(context, "Array should contain no more than " +
boost::lexical_cast<std::string>(maxItems) + " elements."); std::to_string(maxItems) + " elements.");
} }
return false; return false;
@ -431,7 +429,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"String should be no more than " + "String should be no more than " +
boost::lexical_cast<std::string>(maxLength) + std::to_string(maxLength) +
" characters in length."); " characters in length.");
} }
@ -459,7 +457,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Object should have no more than " + results->pushError(context, "Object should have no more than " +
boost::lexical_cast<std::string>(maxProperties) + std::to_string(maxProperties) +
" properties."); " properties.");
} }
@ -487,7 +485,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Expected number greater than " + "Expected number greater than " +
boost::lexical_cast<std::string>(minimum)); std::to_string(minimum));
} }
return false; return false;
@ -496,7 +494,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Expected number greater than or equal to " + "Expected number greater than or equal to " +
boost::lexical_cast<std::string>(minimum)); std::to_string(minimum));
} }
return false; return false;
@ -525,7 +523,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Array should contain no fewer than " + results->pushError(context, "Array should contain no fewer than " +
boost::lexical_cast<std::string>(minItems) + " elements."); std::to_string(minItems) + " elements.");
} }
return false; return false;
@ -554,7 +552,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"String should be no fewer than " + "String should be no fewer than " +
boost::lexical_cast<std::string>(minLength) + std::to_string(minLength) +
" characters in length."); " characters in length.");
} }
@ -582,7 +580,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Object should have no fewer than " + results->pushError(context, "Object should have no fewer than " +
boost::lexical_cast<std::string>(minProperties) + std::to_string(minProperties) +
" properties."); " properties.");
} }
@ -606,7 +604,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Value could not be converted " results->pushError(context, "Value could not be converted "
"to a number to check if it is a multiple of " + "to a number to check if it is a multiple of " +
boost::lexical_cast<std::string>(divisor)); std::to_string(divisor));
} }
return false; return false;
} }
@ -616,7 +614,7 @@ public:
if (results) { if (results) {
results->pushError(context, "Value could not be converted " results->pushError(context, "Value could not be converted "
"to a number to check if it is a multiple of " + "to a number to check if it is a multiple of " +
boost::lexical_cast<std::string>(divisor)); std::to_string(divisor));
} }
return false; return false;
} }
@ -634,7 +632,7 @@ public:
if (fabs(r) > std::numeric_limits<double>::epsilon()) { if (fabs(r) > std::numeric_limits<double>::epsilon()) {
if (results) { if (results) {
results->pushError(context, "Value should be a multiple of " + results->pushError(context, "Value should be a multiple of " +
boost::lexical_cast<std::string>(divisor)); std::to_string(divisor));
} }
return false; return false;
} }
@ -683,7 +681,7 @@ public:
if (i % divisor != 0) { if (i % divisor != 0) {
if (results) { if (results) {
results->pushError(context, "Value should be a multiple of " + results->pushError(context, "Value should be a multiple of " +
boost::lexical_cast<std::string>(divisor)); std::to_string(divisor));
} }
return false; return false;
} }
@ -777,11 +775,10 @@ public:
return true; return true;
} }
const boost::regex patternRegex( const std::regex patternRegex(
constraint.getPattern<std::string::allocator_type>(), constraint.getPattern<std::string::allocator_type>());
boost::regex::perl);
if (!boost::regex_search(target.asString(), patternRegex)) { if (!std::regex_search(target.asString(), patternRegex)) {
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Failed to match regex specified by 'pattern' " "Failed to match regex specified by 'pattern' "
@ -878,7 +875,7 @@ public:
return validated; return validated;
} }
BOOST_FOREACH( const typename AdapterType::ObjectMember m, object ) { for (const typename AdapterType::ObjectMember m : object) {
if (propertiesMatched.find(m.first) == propertiesMatched.end()) { if (propertiesMatched.find(m.first) == propertiesMatched.end()) {
// Update context // Update context
std::vector<std::string> newContext = context; std::vector<std::string> newContext = context;
@ -959,11 +956,11 @@ public:
bool validated = true; bool validated = true;
unsigned int index = 0; unsigned int index = 0;
BOOST_FOREACH( const AdapterType &item, target.getArray() ) { for (const AdapterType &item : target.getArray()) {
// Update context for current array item // Update context for current array item
std::vector<std::string> newContext = context; std::vector<std::string> newContext = context;
newContext.push_back("[" + newContext.push_back("[" +
boost::lexical_cast<std::string>(index) + "]"); std::to_string(index) + "]");
// Create a validator for the current array item // Create a validator for the current array item
ValidationVisitor<AdapterType> validationVisitor(item, ValidationVisitor<AdapterType> validationVisitor(item,
@ -974,7 +971,7 @@ public:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Failed to validate item #" + "Failed to validate item #" +
boost::lexical_cast<std::string>(index) + std::to_string(index) +
" in array."); " in array.");
validated = false; validated = false;
} else { } else {
@ -1062,8 +1059,8 @@ public:
if (outerItr->equalTo(*innerItr, true)) { if (outerItr->equalTo(*innerItr, true)) {
if (results) { if (results) {
results->pushError(context, "Elements at indexes #" + results->pushError(context, "Elements at indexes #" +
boost::lexical_cast<std::string>(outerIndex) + " and #" + std::to_string(outerIndex) + " and #" +
boost::lexical_cast<std::string>(innerIndex) + " violate uniqueness constraint."); std::to_string(innerIndex) + " violate uniqueness constraint.");
validated = false; validated = false;
} else { } else {
return false; return false;
@ -1202,7 +1199,7 @@ private:
} }
typedef typename ContainerType::value_type ValueType; typedef typename ContainerType::value_type ValueType;
BOOST_FOREACH( const ValueType &dependencyName, dependencyNames ) { for (const ValueType &dependencyName : dependencyNames) {
const std::string dependencyNameKey(dependencyName.c_str()); const std::string dependencyNameKey(dependencyName.c_str());
if (object.find(dependencyNameKey) == object.end()) { if (object.find(dependencyNameKey) == object.end()) {
if (validated) { if (validated) {
@ -1260,7 +1257,7 @@ private:
// Update context // Update context
std::vector<std::string> newContext = context; std::vector<std::string> newContext = context;
newContext.push_back( newContext.push_back(
"[" + boost::lexical_cast<std::string>(index) + "]"); "[" + std::to_string(index) + "]");
// Find array item // Find array item
typename AdapterType::Array::const_iterator itr = arr.begin(); typename AdapterType::Array::const_iterator itr = arr.begin();
@ -1283,7 +1280,7 @@ private:
if (results) { if (results) {
results->pushError(newContext, results->pushError(newContext,
"Failed to validate item #" + "Failed to validate item #" +
boost::lexical_cast<std::string>(index) + std::to_string(index) +
" against corresponding item schema."); " against corresponding item schema.");
} }
@ -1405,17 +1402,17 @@ private:
const std::string patternPropertyStr(patternProperty.c_str()); const std::string patternPropertyStr(patternProperty.c_str());
// It would be nice to store pre-allocated regex objects in the // It would be nice to store pre-allocated regex objects in the
// PropertiesConstraint, but boost::regex does not currently support // PropertiesConstraint. does std::regex currently support
// custom allocators. This isn't an issue here, because Valijson's // custom allocators? Anyway, this isn't an issue here, because Valijson's
// JSON Scheme validator does not yet support custom allocators. // JSON Scheme validator does not yet support custom allocators.
const boost::regex r(patternPropertyStr, boost::regex::perl); const std::regex r(patternPropertyStr);
bool matchFound = false; bool matchFound = false;
// Recursively validate all matching properties // Recursively validate all matching properties
typedef const typename AdapterType::ObjectMember ObjectMember; typedef const typename AdapterType::ObjectMember ObjectMember;
BOOST_FOREACH( const ObjectMember m, object ) { for (const ObjectMember m : object) {
if (boost::regex_search(m.first, r)) { if (std::regex_search(m.first, r)) {
matchFound = true; matchFound = true;
if (propertiesMatched) { if (propertiesMatched) {
propertiesMatched->insert(m.first); propertiesMatched->insert(m.first);
@ -1647,7 +1644,7 @@ private:
if (results) { if (results) {
results->pushError(context, results->pushError(context,
"Failed to validate against child schema #" + "Failed to validate against child schema #" +
boost::lexical_cast<std::string>(index) + "."); std::to_string(index) + ".");
} }
return continueOnFailure; return continueOnFailure;

View File

@ -2,9 +2,6 @@
#ifndef __VALIJSON_VALIDATOR_HPP #ifndef __VALIJSON_VALIDATOR_HPP
#define __VALIJSON_VALIDATOR_HPP #define __VALIJSON_VALIDATOR_HPP
#include <boost/bind.hpp>
#include <boost/scoped_ptr.hpp>
#include <valijson/schema.hpp> #include <valijson/schema.hpp>
#include <valijson/validation_visitor.hpp> #include <valijson/validation_visitor.hpp>

View File

@ -1,8 +1,5 @@
#include <picojson.h> #include <picojson.h>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <valijson/adapters/jsoncpp_adapter.hpp> #include <valijson/adapters/jsoncpp_adapter.hpp>

View File

@ -1,4 +1,3 @@
#include <boost/make_shared.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>

View File

@ -1,8 +1,5 @@
#ifdef VALIJSON_BUILD_CXX11_ADAPTERS #ifdef VALIJSON_BUILD_CXX11_ADAPTERS
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <valijson/adapters/json11_adapter.hpp> #include <valijson/adapters/json11_adapter.hpp>
@ -38,7 +35,7 @@ TEST_F(TestJson11Adapter, BasicArrayIteration)
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::Json11Adapter value, adapter.getArray() ) { for (const valijson::adapters::Json11Adapter value : adapter.getArray()) {
ASSERT_TRUE( value.isNumber() ); ASSERT_TRUE( value.isNumber() );
EXPECT_EQ( double(expectedValue), value.getDouble() ); EXPECT_EQ( double(expectedValue), value.getDouble() );
expectedValue++; expectedValue++;
@ -56,7 +53,7 @@ TEST_F(TestJson11Adapter, BasicObjectIteration)
// strings their corresponding numeric values // strings their corresponding numeric values
json11::Json::object object; json11::Json::object object;
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
std::string name(boost::lexical_cast<std::string>(i)); std::string name(std::to_string(i));
object[name] = json11::Json(static_cast<double>(i)); object[name] = json11::Json(static_cast<double>(i));
} }
json11::Json document(object); json11::Json document(object);
@ -75,9 +72,9 @@ TEST_F(TestJson11Adapter, BasicObjectIteration)
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::Json11Adapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::Json11Adapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isNumber() ); ASSERT_TRUE( member.second.isNumber() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.getDouble() ); EXPECT_EQ( double(expectedValue), member.second.getDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,5 +1,4 @@
#include <boost/make_shared.hpp> #include <memory>
#include <boost/shared_ptr.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -36,43 +35,43 @@ struct JsonPointerTestCase
rapidjson::Value *expectedValue; rapidjson::Value *expectedValue;
}; };
std::vector<boost::shared_ptr<JsonPointerTestCase> > std::vector<std::shared_ptr<JsonPointerTestCase> >
testCasesForSingleLevelObjectPointers( testCasesForSingleLevelObjectPointers(
RapidJsonCrtAllocator &allocator) RapidJsonCrtAllocator &allocator)
{ {
typedef boost::shared_ptr<JsonPointerTestCase> TestCase; typedef std::shared_ptr<JsonPointerTestCase> TestCase;
std::vector<TestCase> testCases; std::vector<TestCase> testCases;
TestCase testCase = boost::make_shared<JsonPointerTestCase>( TestCase testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '#' should cause an exception to be thrown"); "Resolving '#' should cause an exception to be thrown");
testCase->value.SetNull(); testCase->value.SetNull();
testCase->jsonPointer = "#"; testCase->jsonPointer = "#";
testCase->expectedValue = NULL; testCase->expectedValue = NULL;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving an empty string should return the root node"); "Resolving an empty string should return the root node");
testCase->value.SetNull(); testCase->value.SetNull();
testCase->jsonPointer = ""; testCase->jsonPointer = "";
testCase->expectedValue = &testCase->value; testCase->expectedValue = &testCase->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/' should return the root node"); "Resolving '/' should return the root node");
testCase->value.SetNull(); testCase->value.SetNull();
testCase->jsonPointer = "/"; testCase->jsonPointer = "/";
testCase->expectedValue = &testCase->value; testCase->expectedValue = &testCase->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '//' should return the root node"); "Resolving '//' should return the root node");
testCase->value.SetNull(); testCase->value.SetNull();
testCase->jsonPointer = "//"; testCase->jsonPointer = "//";
testCase->expectedValue = &testCase->value; testCase->expectedValue = &testCase->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/test' in object containing one member named 'test'"); "Resolve '/test' in object containing one member named 'test'");
testCase->value.SetObject(); testCase->value.SetObject();
testCase->value.AddMember("test", "test", allocator); testCase->value.AddMember("test", "test", allocator);
@ -80,7 +79,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testCase->expectedValue = &testCase->value.FindMember("test")->value; testCase->expectedValue = &testCase->value.FindMember("test")->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/test/' in object containing one member named 'test'"); "Resolve '/test/' in object containing one member named 'test'");
testCase->value.SetObject(); testCase->value.SetObject();
testCase->value.AddMember("test", "test", allocator); testCase->value.AddMember("test", "test", allocator);
@ -88,7 +87,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testCase->expectedValue = &testCase->value.FindMember("test")->value; testCase->expectedValue = &testCase->value.FindMember("test")->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '//test//' in object containing one member named 'test'"); "Resolve '//test//' in object containing one member named 'test'");
testCase->value.SetObject(); testCase->value.SetObject();
testCase->value.AddMember("test", "test", allocator); testCase->value.AddMember("test", "test", allocator);
@ -96,7 +95,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testCase->expectedValue = &testCase->value.FindMember("test")->value; testCase->expectedValue = &testCase->value.FindMember("test")->value;
testCases.push_back(testCase); testCases.push_back(testCase);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/missing' in object containing one member name 'test'"); "Resolve '/missing' in object containing one member name 'test'");
testCase->value.SetObject(); testCase->value.SetObject();
testCase->value.AddMember("test", "test", allocator); testCase->value.AddMember("test", "test", allocator);
@ -111,7 +110,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testArray.PushBack("test1", allocator); testArray.PushBack("test1", allocator);
testArray.PushBack("test2", allocator); testArray.PushBack("test2", allocator);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/test/0' in object containing one member containing " "Resolve '/test/0' in object containing one member containing "
"an array with 3 elements"); "an array with 3 elements");
testCase->value.SetObject(); testCase->value.SetObject();
@ -128,7 +127,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testArray.PushBack("test1", allocator); testArray.PushBack("test1", allocator);
testArray.PushBack("test2", allocator); testArray.PushBack("test2", allocator);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/test/1' in object containing one member containing " "Resolve '/test/1' in object containing one member containing "
"an array with 3 elements"); "an array with 3 elements");
testCase->value.SetObject(); testCase->value.SetObject();
@ -145,7 +144,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testArray.PushBack("test1", allocator); testArray.PushBack("test1", allocator);
testArray.PushBack("test2", allocator); testArray.PushBack("test2", allocator);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolve '/test/2' in object containing one member containing " "Resolve '/test/2' in object containing one member containing "
"an array with 3 elements"); "an array with 3 elements");
testCase->value.SetObject(); testCase->value.SetObject();
@ -162,7 +161,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testArray.PushBack("test1", allocator); testArray.PushBack("test1", allocator);
testArray.PushBack("test2", allocator); testArray.PushBack("test2", allocator);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/test/3' in object containing one member containing " "Resolving '/test/3' in object containing one member containing "
"an array with 3 elements should throw an exception"); "an array with 3 elements should throw an exception");
testCase->value.SetObject(); testCase->value.SetObject();
@ -193,7 +192,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
testArray.PushBack("test1", allocator); testArray.PushBack("test1", allocator);
testArray.PushBack("test2", allocator); testArray.PushBack("test2", allocator);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/test/-' in object containing one member containing " "Resolving '/test/-' in object containing one member containing "
"an array with 3 elements should throw an exception"); "an array with 3 elements should throw an exception");
testCase->value.SetNull(); testCase->value.SetNull();
@ -221,7 +220,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
rapidjson::Value value; rapidjson::Value value;
value.SetDouble(10.); value.SetDouble(10.);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/hello~1world' in object containing one member named " "Resolving '/hello~1world' in object containing one member named "
"'hello/world' should return the associated value"); "'hello/world' should return the associated value");
testCase->value.SetObject(); testCase->value.SetObject();
@ -235,7 +234,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
rapidjson::Value value; rapidjson::Value value;
value.SetDouble(10.); value.SetDouble(10.);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/hello~0world' in object containing one member named " "Resolving '/hello~0world' in object containing one member named "
"'hello~world' should return the associated value"); "'hello~world' should return the associated value");
testCase->value.SetObject(); testCase->value.SetObject();
@ -249,7 +248,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
rapidjson::Value value; rapidjson::Value value;
value.SetDouble(10.); value.SetDouble(10.);
testCase = boost::make_shared<JsonPointerTestCase>( testCase = std::make_shared<JsonPointerTestCase>(
"Resolving '/hello~01world' in object containing one member named " "Resolving '/hello~01world' in object containing one member named "
"'hello~1world' should return the associated value"); "'hello~1world' should return the associated value");
testCase->value.SetObject(); testCase->value.SetObject();
@ -264,7 +263,7 @@ std::vector<boost::shared_ptr<JsonPointerTestCase> >
TEST_F(TestJsonPointer, JsonPointerTestCases) TEST_F(TestJsonPointer, JsonPointerTestCases)
{ {
typedef std::vector<boost::shared_ptr<JsonPointerTestCase> > TestCases; typedef std::vector<std::shared_ptr<JsonPointerTestCase> > TestCases;
// Ensure memory used for test cases is freed when test function completes // Ensure memory used for test cases is freed when test function completes
rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> allocator; rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> allocator;

View File

@ -1,5 +1,3 @@
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -34,7 +32,7 @@ TEST_F(TestJsonCppAdapter, BasicArrayIteration)
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::JsonCppAdapter value, adapter.getArray() ) { for (const valijson::adapters::JsonCppAdapter value : adapter.getArray()) {
ASSERT_TRUE( value.isNumber() ); ASSERT_TRUE( value.isNumber() );
EXPECT_EQ( double(expectedValue), value.getNumber() ); EXPECT_EQ( double(expectedValue), value.getNumber() );
expectedValue++; expectedValue++;
@ -52,7 +50,7 @@ TEST_F(TestJsonCppAdapter, BasicObjectIteration)
// strings their corresponding numeric values // strings their corresponding numeric values
Json::Value document(Json::objectValue); Json::Value document(Json::objectValue);
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
std::string name(boost::lexical_cast<std::string>(i)); std::string name(std::to_string(i));
document[name] = Json::Value(double(i)); document[name] = Json::Value(double(i));
} }
@ -70,9 +68,9 @@ TEST_F(TestJsonCppAdapter, BasicObjectIteration)
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::JsonCppAdapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::JsonCppAdapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isNumber() ); ASSERT_TRUE( member.second.isNumber() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.getDouble() ); EXPECT_EQ( double(expectedValue), member.second.getDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,8 +1,5 @@
#ifdef VALIJSON_BUILD_CXX11_ADAPTERS #ifdef VALIJSON_BUILD_CXX11_ADAPTERS
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <valijson/adapters/nlohmann_json_adapter.hpp> #include <valijson/adapters/nlohmann_json_adapter.hpp>
@ -37,7 +34,7 @@ TEST_F(TestNlohmannJsonAdapter, BasicArrayIteration)
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::NlohmannJsonAdapter value, adapter.getArray() ) { for (const valijson::adapters::NlohmannJsonAdapter value : adapter.getArray()) {
ASSERT_TRUE( value.isNumber() ); ASSERT_TRUE( value.isNumber() );
EXPECT_EQ( double(expectedValue), value.getDouble() ); EXPECT_EQ( double(expectedValue), value.getDouble() );
expectedValue++; expectedValue++;
@ -55,7 +52,7 @@ TEST_F(TestNlohmannJsonAdapter, BasicObjectIteration)
// strings their corresponding numeric values // strings their corresponding numeric values
nlohmann::json document; nlohmann::json document;
for (uint32_t i = 0; i < numElements; i++) { for (uint32_t i = 0; i < numElements; i++) {
document[boost::lexical_cast<std::string>(i)] = static_cast<double>(i); document[std::to_string(i)] = static_cast<double>(i);
} }
// Ensure that wrapping the document preserves the object and does not // Ensure that wrapping the document preserves the object and does not
@ -72,9 +69,9 @@ TEST_F(TestNlohmannJsonAdapter, BasicObjectIteration)
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::NlohmannJsonAdapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::NlohmannJsonAdapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isNumber() ); ASSERT_TRUE( member.second.isNumber() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.getDouble() ); EXPECT_EQ( double(expectedValue), member.second.getDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,5 +1,4 @@
#include <boost/foreach.hpp> #include <string>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -36,7 +35,7 @@ TEST_F(TestPicoJsonAdapter, BasicArrayIteration)
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::PicoJsonAdapter value, adapter.getArray() ) { for (const valijson::adapters::PicoJsonAdapter value : adapter.getArray()) {
ASSERT_TRUE( value.isNumber() ); ASSERT_TRUE( value.isNumber() );
EXPECT_EQ( double(expectedValue), value.getDouble() ); EXPECT_EQ( double(expectedValue), value.getDouble() );
expectedValue++; expectedValue++;
@ -54,7 +53,7 @@ TEST_F(TestPicoJsonAdapter, BasicObjectIteration)
// strings their corresponding numeric values // strings their corresponding numeric values
picojson::object object; picojson::object object;
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
std::string name(boost::lexical_cast<std::string>(i)); std::string name(std::to_string(i));
object[name] = picojson::value(static_cast<double>(i)); object[name] = picojson::value(static_cast<double>(i));
} }
picojson::value document(object); picojson::value document(object);
@ -73,9 +72,9 @@ TEST_F(TestPicoJsonAdapter, BasicObjectIteration)
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::PicoJsonAdapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::PicoJsonAdapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isNumber() ); ASSERT_TRUE( member.second.isNumber() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.getDouble() ); EXPECT_EQ( double(expectedValue), member.second.getDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,5 +1,3 @@
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -19,7 +17,7 @@ TEST_F(TestPropertyTreeAdapter, BasicArrayIteration)
boost::property_tree::ptree document; boost::property_tree::ptree document;
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
document.push_back(std::make_pair(std::string(), document.push_back(std::make_pair(std::string(),
boost::property_tree::ptree(boost::lexical_cast<std::string>(i)))); boost::property_tree::ptree(std::to_string(i))));
} }
// Ensure that wrapping the document preserves the array and does not allow // Ensure that wrapping the document preserves the array and does not allow
@ -36,7 +34,7 @@ TEST_F(TestPropertyTreeAdapter, BasicArrayIteration)
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::PropertyTreeAdapter value, adapter.getArray() ) { for (const valijson::adapters::PropertyTreeAdapter value : adapter.getArray()) {
ASSERT_TRUE( value.isString() ); ASSERT_TRUE( value.isString() );
ASSERT_FALSE( value.isNumber() ); ASSERT_FALSE( value.isNumber() );
ASSERT_TRUE( value.maybeDouble() ); ASSERT_TRUE( value.maybeDouble() );
@ -56,9 +54,9 @@ TEST_F(TestPropertyTreeAdapter, BasicObjectIteration)
// strings their corresponding numeric values // strings their corresponding numeric values
boost::property_tree::ptree document; boost::property_tree::ptree document;
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
std::string name(boost::lexical_cast<std::string>(i)); std::string name(std::to_string(i));
document.push_back(std::make_pair(name, boost::property_tree::ptree( document.push_back(std::make_pair(name, boost::property_tree::ptree(
boost::lexical_cast<std::string>(double(i))))); std::to_string(double(i)))));
} }
// Ensure that wrapping the document preserves the object and does not // Ensure that wrapping the document preserves the object and does not
@ -75,11 +73,11 @@ TEST_F(TestPropertyTreeAdapter, BasicObjectIteration)
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::PropertyTreeAdapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::PropertyTreeAdapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isString() ); ASSERT_TRUE( member.second.isString() );
ASSERT_FALSE( member.second.isNumber() ); ASSERT_FALSE( member.second.isNumber() );
ASSERT_TRUE( member.second.maybeDouble() ); ASSERT_TRUE( member.second.maybeDouble() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.asDouble() ); EXPECT_EQ( double(expectedValue), member.second.asDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,5 +1,4 @@
#include <boost/foreach.hpp> #include <string>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -38,7 +37,7 @@ void testBasicArrayIteration()
// Ensure that the elements are returned in the order they were inserted // Ensure that the elements are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::RapidJsonAdapter value, adapter.getArray() ) { for (const valijson::adapters::RapidJsonAdapter value : adapter.getArray()) {
ASSERT_TRUE( value.isNumber() ); ASSERT_TRUE( value.isNumber() );
EXPECT_EQ( double(expectedValue), value.getDouble() ); EXPECT_EQ( double(expectedValue), value.getDouble() );
expectedValue++; expectedValue++;
@ -59,7 +58,7 @@ void testBasicObjectIteration()
document.SetObject(); document.SetObject();
for (unsigned int i = 0; i < numElements; i++) { for (unsigned int i = 0; i < numElements; i++) {
rapidjson::Value name, value; rapidjson::Value name, value;
name.SetString(boost::lexical_cast<std::string>(i).c_str(), document.GetAllocator()); name.SetString(std::to_string(i).c_str(), document.GetAllocator());
value.SetDouble(i); value.SetDouble(i);
document.AddMember(name, value, document.GetAllocator()); document.AddMember(name, value, document.GetAllocator());
} }
@ -78,9 +77,9 @@ void testBasicObjectIteration()
// Ensure that the members are returned in the order they were inserted // Ensure that the members are returned in the order they were inserted
unsigned int expectedValue = 0; unsigned int expectedValue = 0;
BOOST_FOREACH( const valijson::adapters::RapidJsonAdapter::ObjectMember member, adapter.getObject() ) { for (const valijson::adapters::RapidJsonAdapter::ObjectMember member : adapter.getObject()) {
ASSERT_TRUE( member.second.isNumber() ); ASSERT_TRUE( member.second.isNumber() );
EXPECT_EQ( boost::lexical_cast<std::string>(expectedValue), member.first ); EXPECT_EQ( std::to_string(expectedValue), member.first );
EXPECT_EQ( double(expectedValue), member.second.getDouble() ); EXPECT_EQ( double(expectedValue), member.second.getDouble() );
expectedValue++; expectedValue++;
} }

View File

@ -1,8 +1,5 @@
#include <iostream> #include <iostream>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <valijson/adapters/rapidjson_adapter.hpp> #include <valijson/adapters/rapidjson_adapter.hpp>

View File

@ -2,9 +2,6 @@
#include <iostream> #include <iostream>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <valijson/adapters/jsoncpp_adapter.hpp> #include <valijson/adapters/jsoncpp_adapter.hpp>
@ -99,7 +96,7 @@ protected:
ASSERT_TRUE( testCases.isArray() ); ASSERT_TRUE( testCases.isArray() );
// Process each test case in the file // Process each test case in the file
BOOST_FOREACH( const AdapterType testCase, testCases.getArray() ) { for (const AdapterType testCase : testCases.getArray()) {
currentTestCase.clear(); currentTestCase.clear();
currentTest.clear(); currentTest.clear();
@ -127,7 +124,7 @@ protected:
itr = object.find("tests"); itr = object.find("tests");
ASSERT_NE( object.end(), itr ); ASSERT_NE( object.end(), itr );
ASSERT_TRUE( itr->second.isArray() ); ASSERT_TRUE( itr->second.isArray() );
BOOST_FOREACH( const AdapterType test, itr->second.getArray() ) { for (const AdapterType test : itr->second.getArray()) {
const bool strict = itr->second.hasStrictTypes(); const bool strict = itr->second.hasStrictTypes();

View File

@ -26,22 +26,10 @@ if [[ $CXX == 'clang++' ]]; then
echo "Additional flags to pass to cmake: $CMAKE_FLAGS" echo "Additional flags to pass to cmake: $CMAKE_FLAGS"
fi fi
echo "Attempting to build and run test suite with C++11 support disabled..." echo "Attempting to build and run test suite with C++11 support enabled..."
cmake $CMAKE_FLAGS -DVALIJSON_CXX11_ADAPTERS=disabled .. cmake $CMAKE_FLAGS -DVALIJSON_CXX11_ADAPTERS=enabled ..
VERBOSE=1 make VERBOSE=1 make
./test_suite ./test_suite
echo "Checking if current compiler is GCC..."
if [[ $CXX == 'g++' ]]; then
echo "Not building test suite with C++11 support due to ancient version of GCC on Travis CI"
else
echo "Attempting to build and run test suite with C++11 support enabled..."
make clean
cmake $CMAKE_FLAGS -DVALIJSON_CXX11_ADAPTERS=enabled ..
VERBOSE=1 make
./test_suite
fi
make clean make clean
popd > /dev/null popd > /dev/null

View File

@ -52,6 +52,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
462CB4C31D50940F003DC976 /* optional.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = optional.hpp; path = compat/optional.hpp; sourceTree = "<group>"; };
6A309D2D1C28C1FD00EF761C /* subschema.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = subschema.hpp; sourceTree = "<group>"; }; 6A309D2D1C28C1FD00EF761C /* subschema.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = subschema.hpp; sourceTree = "<group>"; };
6A34698C1BD109A900C97DA2 /* json_reference.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = json_reference.hpp; path = internal/json_reference.hpp; sourceTree = "<group>"; }; 6A34698C1BD109A900C97DA2 /* json_reference.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = json_reference.hpp; path = internal/json_reference.hpp; sourceTree = "<group>"; };
6A356B0D1C1CFD020007EB8B /* uri.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = uri.hpp; path = internal/uri.hpp; sourceTree = "<group>"; }; 6A356B0D1C1CFD020007EB8B /* uri.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = uri.hpp; path = internal/uri.hpp; sourceTree = "<group>"; };
@ -335,6 +336,14 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
462CB4C41D50941E003DC976 /* compat */ = {
isa = PBXGroup;
children = (
462CB4C31D50940F003DC976 /* optional.hpp */,
);
name = compat;
sourceTree = "<group>";
};
6A477F8717D6EEF20013571C /* Frameworks */ = { 6A477F8717D6EEF20013571C /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -846,6 +855,7 @@
6AC78BDC17C5FC5F00674114 /* include */ = { 6AC78BDC17C5FC5F00674114 /* include */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
462CB4C41D50941E003DC976 /* compat */,
6AC78BDD17C5FC6A00674114 /* valijson */, 6AC78BDD17C5FC6A00674114 /* valijson */,
); );
name = include; name = include;