Merge branch 'get_or' to load default value: #6

This commit is contained in:
ToruNiina
2017-12-11 14:55:43 +09:00
5 changed files with 117 additions and 2 deletions

View File

@@ -39,4 +39,4 @@ script:
- git clone https://github.com/toml-lang/toml.git - git clone https://github.com/toml-lang/toml.git
- cmake -DCMAKE_CXX_COMPILER=$COMPILER .. - cmake -DCMAKE_CXX_COMPILER=$COMPILER ..
- make - make
- make test - ctest --output-on-failure

View File

@@ -109,6 +109,19 @@ const auto& num1 = numbers.at(1).cast<toml::value_t::Integer>();
const auto& num2 = numbers.at(2).cast<toml::value_t::Integer>(); const auto& num2 = numbers.at(2).cast<toml::value_t::Integer>();
``` ```
#### 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 #### toml::value\_t
When you don't know the exact type of toml-value, you can get `enum` type from When you don't know the exact type of toml-value, you can get `enum` type from

View File

@@ -5,6 +5,7 @@ set(TEST_NAMES
test_to_toml test_to_toml
test_from_toml test_from_toml
test_get test_get
test_get_or
test_value_operator test_value_operator
test_datetime test_datetime
test_acceptor test_acceptor

88
tests/test_get_or.cpp Normal file
View File

@@ -0,0 +1,88 @@
#define BOOST_TEST_MODULE "test_get_or"
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif
#include <toml.hpp>
#include <map>
#include <unordered_map>
#include <list>
#include <deque>
#include <array>
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<toml::value_t::Integer>(), raw_v5.at(0).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(1).cast<toml::value_t::Integer>(), raw_v5.at(1).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(2).cast<toml::value_t::Integer>(), raw_v5.at(2).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(3).cast<toml::value_t::Integer>(), raw_v5.at(3).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(4).cast<toml::value_t::Integer>(), raw_v5.at(4).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u6.at("key").cast<toml::value_t::Integer>(), 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<toml::value_t::Integer>(), raw_v5.at(0).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(1).cast<toml::value_t::Integer>(), raw_v5.at(1).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(2).cast<toml::value_t::Integer>(), raw_v5.at(2).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(3).cast<toml::value_t::Integer>(), raw_v5.at(3).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u5.at(4).cast<toml::value_t::Integer>(), raw_v5.at(4).cast<toml::value_t::Integer>());
BOOST_CHECK_EQUAL(u6.at("key").cast<toml::value_t::Integer>(), 42);
}

View File

@@ -14,7 +14,7 @@ inline T get(const toml::value& v)
return static_cast<T>(v.cast<vT>()); return static_cast<T>(v.cast<vT>());
} }
// array case // array-like type
template<typename T, toml::value_t vT = toml::detail::check_type<T>(), template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
typename std::enable_if<(vT == toml::value_t::Unknown) && typename std::enable_if<(vT == toml::value_t::Unknown) &&
(!toml::detail::is_map<T>::value) && (!toml::detail::is_map<T>::value) &&
@@ -24,6 +24,7 @@ T get(const toml::value& v)
if(v.type() != value_t::Array) if(v.type() != value_t::Array)
throw type_error("get: value type: " + stringize(v.type()) + throw type_error("get: value type: " + stringize(v.type()) +
std::string(" is not argument type: Array")); std::string(" is not argument type: Array"));
const auto& ar = v.cast<value_t::Array>(); const auto& ar = v.cast<value_t::Array>();
T tmp; T tmp;
try try
@@ -39,6 +40,7 @@ T get(const toml::value& v)
return tmp; return tmp;
} }
// table-like case
template<typename T, toml::value_t vT = toml::detail::check_type<T>(), template<typename T, toml::value_t vT = toml::detail::check_type<T>(),
typename std::enable_if<(vT == toml::value_t::Unknown) && typename std::enable_if<(vT == toml::value_t::Unknown) &&
toml::detail::is_map<T>::value, std::nullptr_t>::type = nullptr> toml::detail::is_map<T>::value, std::nullptr_t>::type = nullptr>
@@ -53,5 +55,16 @@ T get(const toml::value& v)
return tmp; return tmp;
} }
// get_or -----------------------------------------------------------------
template<typename T>
inline typename std::remove_cv<typename std::remove_reference<T>::type>::type
get_or(const toml::Table& tab, const toml::key& ky, T&& opt)
{
if(tab.count(ky) == 0) {return std::forward<T>(opt);}
return get<typename std::remove_cv<
typename std::remove_reference<T>::type>::type>(tab.find(ky)->second);
}
} // toml } // toml
#endif// TOML11_GET #endif// TOML11_GET