diff --git a/.travis.yml b/.travis.yml index cc79b33..b549f32 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,4 +39,4 @@ script: - git clone https://github.com/toml-lang/toml.git - cmake -DCMAKE_CXX_COMPILER=$COMPILER .. - make -- make test +- ctest --output-on-failure diff --git a/README.md b/README.md index 225ef74..c9c9934 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,19 @@ const auto& num1 = numbers.at(1).cast(); const auto& num2 = numbers.at(2).cast(); ``` +#### toml::get\_or + +You can also set default value for `toml::get`. + +```cpp +toml::Table data; // empty table! + +const auto value1 = toml::get_or(data, "key1", 42); // value1 => int 42. + +toml::Integer i(123); +const auto value2 = toml::get_or(data, "key1", i); // value2 => toml::Integer 42. +``` + #### toml::value\_t When you don't know the exact type of toml-value, you can get `enum` type from diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 09cccef..51ca609 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,6 +5,7 @@ set(TEST_NAMES test_to_toml test_from_toml test_get + test_get_or test_value_operator test_datetime test_acceptor diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp new file mode 100644 index 0000000..4ca863f --- /dev/null +++ b/tests/test_get_or.cpp @@ -0,0 +1,88 @@ +#define BOOST_TEST_MODULE "test_get_or" +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +#include +#else +#define BOOST_TEST_NO_LIB +#include +#endif +#include +#include +#include +#include +#include +#include + + +BOOST_AUTO_TEST_CASE(test_get_or_exist) +{ + toml::Boolean raw_v1(true); + toml::Integer raw_v2(42); + toml::Float raw_v3(3.14); + toml::String raw_v4("hoge"); + toml::Array raw_v5{2,7,1,8,2}; + toml::Table raw_v6{{"key", 42}}; + + toml::value v1(raw_v1); + toml::value v2(raw_v2); + toml::value v3(raw_v3); + toml::value v4(raw_v4); + toml::value v5(raw_v5); + toml::value v6(raw_v6); + + toml::Table table{ + {"value1", v1}, + {"value2", v2}, + {"value3", v3}, + {"value4", v4}, + {"value5", v5}, + {"value6", v6} + }; + + toml::Boolean u1 = toml::get_or(table, "value1", raw_v1); + toml::Integer u2 = toml::get_or(table, "value2", raw_v2); + toml::Float u3 = toml::get_or(table, "value3", raw_v3); + toml::String u4 = toml::get_or(table, "value4", raw_v4); + toml::Array u5 = toml::get_or(table, "value5", raw_v5); + toml::Table u6 = toml::get_or(table, "value6", raw_v6); + + BOOST_CHECK_EQUAL(u1, raw_v1); + BOOST_CHECK_EQUAL(u2, raw_v2); + BOOST_CHECK_EQUAL(u3, raw_v3); + BOOST_CHECK_EQUAL(u4, raw_v4); + BOOST_CHECK_EQUAL(u5.at(0).cast(), raw_v5.at(0).cast()); + BOOST_CHECK_EQUAL(u5.at(1).cast(), raw_v5.at(1).cast()); + BOOST_CHECK_EQUAL(u5.at(2).cast(), raw_v5.at(2).cast()); + BOOST_CHECK_EQUAL(u5.at(3).cast(), raw_v5.at(3).cast()); + BOOST_CHECK_EQUAL(u5.at(4).cast(), raw_v5.at(4).cast()); + BOOST_CHECK_EQUAL(u6.at("key").cast(), 42); +} + +BOOST_AUTO_TEST_CASE(test_get_or_empty) +{ + toml::Boolean raw_v1(true); + toml::Integer raw_v2(42); + toml::Float raw_v3(3.14); + toml::String raw_v4("hoge"); + toml::Array raw_v5{2,7,1,8,2}; + toml::Table raw_v6{{"key", 42}}; + + toml::Table table; // empty! + + toml::Boolean u1 = toml::get_or(table, std::string("value1"), raw_v1); + toml::Integer u2 = toml::get_or(table, std::string("value2"), raw_v2); + toml::Float u3 = toml::get_or(table, std::string("value3"), raw_v3); + toml::String u4 = toml::get_or(table, std::string("value4"), raw_v4); + toml::Array u5 = toml::get_or(table, std::string("value5"), raw_v5); + toml::Table u6 = toml::get_or(table, std::string("value6"), raw_v6); + + BOOST_CHECK_EQUAL(u1, raw_v1); + BOOST_CHECK_EQUAL(u2, raw_v2); + BOOST_CHECK_EQUAL(u3, raw_v3); + BOOST_CHECK_EQUAL(u4, raw_v4); + BOOST_CHECK_EQUAL(u5.at(0).cast(), raw_v5.at(0).cast()); + BOOST_CHECK_EQUAL(u5.at(1).cast(), raw_v5.at(1).cast()); + BOOST_CHECK_EQUAL(u5.at(2).cast(), raw_v5.at(2).cast()); + BOOST_CHECK_EQUAL(u5.at(3).cast(), raw_v5.at(3).cast()); + BOOST_CHECK_EQUAL(u5.at(4).cast(), raw_v5.at(4).cast()); + BOOST_CHECK_EQUAL(u6.at("key").cast(), 42); +} diff --git a/toml/get.hpp b/toml/get.hpp index ea32216..c532fe5 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -14,7 +14,7 @@ inline T get(const toml::value& v) return static_cast(v.cast()); } -// array case +// array-like type template(), typename std::enable_if<(vT == toml::value_t::Unknown) && (!toml::detail::is_map::value) && @@ -24,6 +24,7 @@ T get(const toml::value& v) if(v.type() != value_t::Array) throw type_error("get: value type: " + stringize(v.type()) + std::string(" is not argument type: Array")); + const auto& ar = v.cast(); T tmp; try @@ -39,6 +40,7 @@ T get(const toml::value& v) return tmp; } +// table-like case template(), typename std::enable_if<(vT == toml::value_t::Unknown) && toml::detail::is_map::value, std::nullptr_t>::type = nullptr> @@ -53,5 +55,16 @@ T get(const toml::value& v) return tmp; } +// get_or ----------------------------------------------------------------- + +template +inline typename std::remove_cv::type>::type +get_or(const toml::Table& tab, const toml::key& ky, T&& opt) +{ + if(tab.count(ky) == 0) {return std::forward(opt);} + return get::type>::type>(tab.find(ky)->second); +} + } // toml #endif// TOML11_GET