Compare commits

...

35 Commits

Author SHA1 Message Date
ToruNiina
e12fd4d944 doc: add contributors 2019-10-04 14:28:43 +09:00
ToruNiina
36af02cb3a test: add test cases for one-way conversion 2019-10-04 13:01:15 +09:00
ToruNiina
488015df49 fix: toml -> T is required; related to #83 2019-10-04 13:00:34 +09:00
Toru Niina
1f951e49b1 Merge pull request #84 from jcmoyer/master
Update documentation for toml::from and toml::into
2019-10-04 12:58:13 +09:00
J.C. Moyer
6a7dbb7875 Update documentation for toml::from and toml::into 2019-10-03 21:28:06 -04:00
ToruNiina
ad7eb56634 fix: avoid potential memory bugs related to move 2019-10-03 14:42:52 +09:00
ToruNiina
b01c5534ed test: add test cases for const-ref version 2019-10-03 13:52:12 +09:00
ToruNiina
22dac3c9f2 Merge branch 'value-at' 2019-09-28 19:40:51 +09:00
ToruNiina
d5adfe8c7d refactor: use as_xxx instead of cast<enum>
because cast<enum>() requires `template` specifier inside a template
function. it makes code long.
2019-09-28 17:01:45 +09:00
ToruNiina
4bb8045c84 doc: add basic_value::at. 2019-09-28 16:31:45 +09:00
ToruNiina
babb6ab3fe test: add test case for basic_value::at 2019-09-28 16:22:01 +09:00
ToruNiina
d73bc6076c feat: add basic_value::at(key) and at(idx) 2019-09-28 16:21:51 +09:00
ToruNiina
8d1da6e8b5 test: add test cases for find_or(&&) + conversion 2019-09-28 14:01:33 +09:00
ToruNiina
8276e12f06 test: add test cases for toml::find_or(value&&) 2019-09-28 13:38:59 +09:00
ToruNiina
f3d3f63ff9 fix: return values from find_or(value&&) 2019-09-28 13:38:26 +09:00
ToruNiina
d9689c878d test: add test cases for toml::find(value&&, key) 2019-09-28 13:05:13 +09:00
ToruNiina
df097cb09a test: add test cases of get_or(value&&, U) 2019-09-28 12:13:59 +09:00
ToruNiina
a425e3b7c6 test: add test cases of toml::get_or(value&&, T&&) 2019-09-28 12:08:14 +09:00
ToruNiina
e4b4503b81 style: add comment to test::operator<< 2019-09-28 12:07:53 +09:00
ToruNiina
b44fbad925 fix: remove needless ::type 2019-09-28 11:14:14 +09:00
ToruNiina
826c9444ac refactor: use remove_cvref 2019-09-28 11:03:46 +09:00
ToruNiina
a1095f3e4c refactor: use std::map::at instead of [] 2019-09-28 11:03:14 +09:00
ToruNiina
483a39beb4 refactor: remove unsupported overload
expect<T>(table, ...)
2019-09-28 11:00:35 +09:00
ToruNiina
1409114c96 refactor: add utility meta-func for internal use 2019-09-28 10:58:02 +09:00
ToruNiina
ecfc9d0c5a fix: make return type rvalue when rvalue is passed 2019-09-28 10:31:10 +09:00
ToruNiina
94f76137a3 doc: add description of unreleased toml features 2019-09-05 14:31:05 +09:00
ToruNiina
c2e1aa9a3c Merge branch 'master' into fp-exp-leading-zeroes 2019-09-05 13:50:58 +09:00
ToruNiina
5b5ece6c32 fix: add "unreleased" flag to raw-tab-in-string 2019-09-04 18:10:15 +09:00
ToruNiina
b696e327d7 ci: add options to test toml-head features 2019-09-04 13:37:08 +09:00
ToruNiina
757e5d60be test: add flag for toml-head features to tests 2019-09-04 13:36:42 +09:00
ToruNiina
c02093de7f chore: add an option to tests
that enable/disable to use unreleased toml features
2019-09-04 13:34:28 +09:00
ToruNiina
4f8b62a7e9 feat: add TOML11_USE_UNRELEASED_TOML_FEATURES flag
to choose to use unreleased toml feature
2019-09-04 13:32:05 +09:00
ToruNiina
d9b8582c47 test: add test for toml::get<T>(std::move(v)) 2019-09-01 19:39:37 +09:00
ToruNiina
64e7bdb835 test: add test for leading zeroes in fp exp 2019-08-28 17:49:12 +09:00
ToruNiina
1acf87679e feat: permit leading 0s in exp parts of floats
This is an unreleased feature of toml language, but is merged into
toml-lang/toml:master.
2019-08-28 16:02:10 +09:00
15 changed files with 1156 additions and 240 deletions

View File

@@ -5,7 +5,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: gcc compiler: gcc
env: COMPILER="g++-5" CXX_STANDARD=11 env: COMPILER="g++-5" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -17,7 +17,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: gcc compiler: gcc
env: COMPILER="g++-6" CXX_STANDARD=11 env: COMPILER="g++-6" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -29,7 +29,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: gcc compiler: gcc
env: COMPILER="g++-7" CXX_STANDARD=11 env: COMPILER="g++-7" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -41,7 +41,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: gcc compiler: gcc
env: COMPILER="g++-8" CXX_STANDARD=11 env: COMPILER="g++-8" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -53,7 +53,31 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: gcc compiler: gcc
env: COMPILER="g++-8" CXX_STANDARD=17 env: COMPILER="g++-8" CXX_STANDARD=11 TOML_HEAD=ON
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages:
- g++-8
- boost1.70
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-8" CXX_STANDARD=17 TOML_HEAD=OFF
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
packages:
- g++-8
- boost1.70
- os: linux
language: cpp
compiler: gcc
env: COMPILER="g++-8" CXX_STANDARD=17 TOML_HEAD=ON
addons: addons:
apt: apt:
sources: sources:
@@ -65,7 +89,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-3.7" CXX_STANDARD=11 env: COMPILER="clang++-3.7" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -79,7 +103,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-4.0" CXX_STANDARD=11 env: COMPILER="clang++-4.0" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -93,7 +117,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-5.0" CXX_STANDARD=11 env: COMPILER="clang++-5.0" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -107,7 +131,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-6.0" CXX_STANDARD=11 env: COMPILER="clang++-6.0" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -121,7 +145,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-7" CXX_STANDARD=11 env: COMPILER="clang++-7" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -135,7 +159,7 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-8" CXX_STANDARD=11 env: COMPILER="clang++-8" CXX_STANDARD=11 TOML_HEAD=OFF
addons: addons:
apt: apt:
sources: sources:
@@ -149,7 +173,35 @@ matrix:
- os: linux - os: linux
language: cpp language: cpp
compiler: clang compiler: clang
env: COMPILER="clang++-8" CXX_STANDARD=17 env: COMPILER="clang++-8" CXX_STANDARD=11 TOML_HEAD=ON
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-8
- sourceline: 'ppa:mhier/libboost-latest'
packages:
- g++-8
- clang-8
- boost1.70
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-8" CXX_STANDARD=17 TOML_HEAD=OFF
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-8
- sourceline: 'ppa:mhier/libboost-latest'
packages:
- clang-8
- g++-8
- boost1.70
- os: linux
language: cpp
compiler: clang
env: COMPILER="clang++-8" CXX_STANDARD=17 TOML_HEAD=ON
addons: addons:
apt: apt:
sources: sources:
@@ -179,6 +231,6 @@ script:
- mkdir build - mkdir build
- cd build - cd build
- git clone https://github.com/toml-lang/toml.git - git clone https://github.com/toml-lang/toml.git
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD .. - cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DTOML11_USE_UNRELEASED_TOML_FEATURES=${TOML_HEAD} ..
- make - make
- ctest --output-on-failure - ctest --output-on-failure

View File

@@ -70,6 +70,7 @@ int main()
- [Formatting user-defined error messages](#formatting-user-defined-error-messages) - [Formatting user-defined error messages](#formatting-user-defined-error-messages)
- [Serializing TOML data](#serializing-toml-data) - [Serializing TOML data](#serializing-toml-data)
- [Underlying types](#underlying-types) - [Underlying types](#underlying-types)
- [Unreleased TOML features](#unreleased-toml-features)
- [Breaking Changes from v2](#breaking-changes-from-v2) - [Breaking Changes from v2](#breaking-changes-from-v2)
- [Running Tests](#running-tests) - [Running Tests](#running-tests)
- [Contributors](#contributors) - [Contributors](#contributors)
@@ -453,6 +454,22 @@ class value {
} // toml } // toml
``` ```
### `at()`
You can access to the element of a table and an array by `toml::basic_value::at`.
```cpp
const toml::value v{1,2,3,4,5};
std::cout << v.at(2).as_integer() << std::endl; // 3
const toml::value v{{"foo", 42}, {"bar", 3.14}};
std::cout << v.at("foo").as_integer() << std::endl; // 42
```
If an invalid key (integer for a table, string for an array), it throws
`toml::type_error` for the conversion. If the provided key is out-of-range,
it throws `std::out_of_range`.
## Checking value type ## Checking value type
You can check the type of a value by `is_xxx` function. You can check the type of a value by `is_xxx` function.
@@ -1074,7 +1091,7 @@ namespace toml
template<> template<>
struct from<ext::foo> struct from<ext::foo>
{ {
ext::foo from_toml(const value& v) static ext::foo from_toml(const value& v)
{ {
ext::foo f; ext::foo f;
f.a = find<int >(v, "a"); f.a = find<int >(v, "a");
@@ -1114,7 +1131,7 @@ template<>
struct from<ext::foo> struct from<ext::foo>
{ {
template<typename C, template<typename ...> class M, template<typename ...> class A> template<typename C, template<typename ...> class M, template<typename ...> class A>
ext::foo from_toml(const basic_value<C, M, A>& v) static ext::foo from_toml(const basic_value<C, M, A>& v)
{ {
ext::foo f; ext::foo f;
f.a = find<int >(v, "a"); f.a = find<int >(v, "a");
@@ -1170,7 +1187,7 @@ namespace toml
template<> template<>
struct into<ext::foo> struct into<ext::foo>
{ {
toml::table into_toml(const ext::foo& f) static toml::table into_toml(const ext::foo& f)
{ {
return toml::table{{"a", f.a}, {"b", f.b}, {"c", f.c}}; return toml::table{{"a", f.a}, {"b", f.b}, {"c", f.c}};
} }
@@ -1396,6 +1413,16 @@ not capable of representing a Local Time independent from a specific day.
It is recommended to get `datetime`s as `std::chrono` classes through `toml::get`. It is recommended to get `datetime`s as `std::chrono` classes through `toml::get`.
## Unreleased TOML features
There are some unreleased features in toml-lang/toml:master.
Currently, the following features are available after defining
`TOML11_USE_UNRELEASED_TOML_FEATURES` macro flag.
- Leading zeroes in exponent parts of floats are permitted.
- e.g. `1.0e+01`, `5e+05`
- Allow raw tab characters in basic strings and multi-line basic strings.
## Breaking Changes from v2 ## Breaking Changes from v2
Although toml11 is relatively new library (it's three years old now), it had Although toml11 is relatively new library (it's three years old now), it had
@@ -1465,6 +1492,8 @@ I appreciate the help of the contributors who introduced the great feature to th
- Fixed warnings while type conversion - Fixed warnings while type conversion
- @KerstinKeller - @KerstinKeller
- Added installation script to CMake - Added installation script to CMake
- J.C. Moyer (@jcmoyer)
- Fixed an example code in the documentation
## Licensing terms ## Licensing terms

View File

@@ -50,6 +50,14 @@ if(COMPILER_SUPPORTS_WPEDANTIC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
endif() endif()
option(TOML11_USE_UNRELEASED_TOML_FEATURES
"use features in toml-lang/toml master while testing" OFF)
if(TOML11_USE_UNRELEASED_TOML_FEATURES)
message(STATUS "adding TOML11_USE_UNRELEASED_TOML_FEATURES flag")
add_definitions("-DTOML11_USE_UNRELEASED_TOML_FEATURES")
endif()
# Disable some MSVC warnings # Disable some MSVC warnings
if(MSVC) if(MSVC)
# conversion from 'double' to 'unsigned int', possible loss of data # conversion from 'double' to 'unsigned int', possible loss of data

View File

@@ -33,6 +33,17 @@ struct bar
return toml::table{{"a", this->a}, {"b", this->b}}; return toml::table{{"a", this->a}, {"b", this->b}};
} }
}; };
struct baz
{
int a;
std::string b;
};
struct qux
{
int a;
std::string b;
};
} // extlib } // extlib
namespace toml namespace toml
@@ -54,6 +65,24 @@ struct into<extlib::foo>
return toml::table{{"a", f.a}, {"b", f.b}}; return toml::table{{"a", f.a}, {"b", f.b}};
} }
}; };
template<>
struct from<extlib::baz>
{
static extlib::baz from_toml(const toml::value& v)
{
return extlib::baz{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
}
};
template<>
struct into<extlib::qux>
{
static toml::table into_toml(const extlib::qux& f)
{
return toml::table{{"a", f.a}, {"b", f.b}};
}
};
} // toml } // toml
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -83,6 +112,16 @@ struct bar
return toml::table{{"a", this->a}, {"b", this->b}}; return toml::table{{"a", this->a}, {"b", this->b}};
} }
}; };
struct baz
{
int a;
std::string b;
};
struct qux
{
int a;
std::string b;
};
} // extlib2 } // extlib2
namespace toml namespace toml
@@ -105,6 +144,28 @@ struct into<extlib2::foo>
return toml::table{{"a", f.a}, {"b", f.b}}; return toml::table{{"a", f.a}, {"b", f.b}};
} }
}; };
template<>
struct from<extlib2::baz>
{
template<typename C, template<typename ...> class M, template<typename ...> class A>
static extlib2::baz from_toml(const toml::basic_value<C, M, A>& v)
{
return extlib2::baz{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
}
};
template<>
struct into<extlib2::qux>
{
static toml::basic_value<toml::preserve_comments, std::map>
into_toml(const extlib2::qux& f)
{
return toml::basic_value<toml::preserve_comments, std::map>{
{"a", f.a}, {"b", f.b}
};
}
};
} // toml } // toml
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -188,6 +249,41 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_specialization)
} }
} }
BOOST_AUTO_TEST_CASE(test_conversion_one_way)
{
{
const toml::value v{{"a", 42}, {"b", "baz"}};
const auto baz = toml::get<extlib::baz>(v);
BOOST_TEST(baz.a == 42);
BOOST_TEST(baz.b == "baz");
}
{
const extlib::qux q{42, "qux"};
const toml::value v(q);
BOOST_TEST(toml::find<int>(v, "a") == 42);
BOOST_TEST(toml::find<std::string>(v, "b") == "qux");
}
{
const toml::basic_value<toml::discard_comments, std::map> v{
{"a", 42}, {"b", "baz"}
};
const auto baz = toml::get<extlib2::baz>(v);
BOOST_TEST(baz.a == 42);
BOOST_TEST(baz.b == "baz");
}
{
const extlib::qux q{42, "qux"};
const toml::basic_value<toml::preserve_comments, std::map> v(q);
BOOST_TEST(toml::find<int>(v, "a") == 42);
BOOST_TEST(toml::find<std::string>(v, "b") == "qux");
}
}
BOOST_AUTO_TEST_CASE(test_recursive_conversion) BOOST_AUTO_TEST_CASE(test_recursive_conversion)
{ {
{ {

View File

@@ -27,6 +27,32 @@ using test_value_types = std::tuple<
BOOST_AUTO_TEST_CASE(test_find_throws) BOOST_AUTO_TEST_CASE(test_find_throws)
{ {
// -----------------------------------------------------------------------
// const-reference version
{
// value is not a table
const toml::value v(true);
BOOST_CHECK_THROW(toml::find<toml::boolean>(v, "key"), toml::type_error);
}
{
// the value corresponding to the key is not the expected type
const toml::value v{{"key", 42}};
BOOST_CHECK_THROW(toml::find<toml::boolean>(v, "key"), toml::type_error);
}
{
// the value corresponding to the key is not found
const toml::value v{{"key", 42}};
BOOST_CHECK_THROW(toml::find<toml::integer>(v, "different_key"),
std::out_of_range);
}
{
// the positive control.
const toml::value v{{"key", 42}};
BOOST_TEST(42 == toml::find<int>(v, "key"));
}
// -----------------------------------------------------------------------
// reference version
{ {
// value is not a table // value is not a table
toml::value v(true); toml::value v(true);
@@ -48,6 +74,31 @@ BOOST_AUTO_TEST_CASE(test_find_throws)
toml::value v{{"key", 42}}; toml::value v{{"key", 42}};
BOOST_TEST(42 == toml::find<int>(v, "key")); BOOST_TEST(42 == toml::find<int>(v, "key"));
} }
// -----------------------------------------------------------------------
// move version
{
// value is not a table
toml::value v(true);
BOOST_CHECK_THROW(toml::find<toml::boolean>(std::move(v), "key"), toml::type_error);
}
{
// the value corresponding to the key is not the expected type
toml::value v{{"key", 42}};
BOOST_CHECK_THROW(toml::find<toml::boolean>(std::move(v), "key"), toml::type_error);
}
{
// the value corresponding to the key is not found
toml::value v{{"key", 42}};
BOOST_CHECK_THROW(toml::find<toml::integer>(std::move(v), "different_key"),
std::out_of_range);
}
{
// the positive control.
toml::value v{{"key", 42}};
BOOST_TEST(42 == toml::find<int>(std::move(v), "key"));
}
} }
BOOST_AUTO_TEST_CASE(test_find_recursive) BOOST_AUTO_TEST_CASE(test_find_recursive)
@@ -74,6 +125,9 @@ BOOST_AUTO_TEST_CASE(test_find_recursive)
auto& num2 = toml::find<toml::integer>(v, a, b, c, d); auto& num2 = toml::find<toml::integer>(v, a, b, c, d);
num2 = 42; num2 = 42;
BOOST_TEST(42 == toml::find<int>(v, a, b, c, d)); BOOST_TEST(42 == toml::find<int>(v, a, b, c, d));
auto num3 = toml::find<toml::integer>(std::move(v), a, b, c, d);
BOOST_TEST(42 == num3);
} }
} }
@@ -85,6 +139,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::boolean>(v, "key") = false; toml::find<toml::boolean>(v, "key") = false;
BOOST_TEST(false == toml::find<toml::boolean>(v, "key")); BOOST_TEST(false == toml::find<toml::boolean>(v, "key"));
const auto moved = toml::find<toml::boolean>(std::move(v), "key");
BOOST_TEST(false == moved);
} }
{ {
value_type v{{"key", 42}}; value_type v{{"key", 42}};
@@ -92,6 +149,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::integer>(v, "key") = 54; toml::find<toml::integer>(v, "key") = 54;
BOOST_TEST(toml::integer(54) == toml::find<toml::integer>(v, "key")); BOOST_TEST(toml::integer(54) == toml::find<toml::integer>(v, "key"));
const auto moved = toml::find<toml::integer>(std::move(v), "key");
BOOST_TEST(toml::integer(54) == moved);
} }
{ {
value_type v{{"key", 3.14}}; value_type v{{"key", 3.14}};
@@ -99,6 +159,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::floating>(v, "key") = 2.71; toml::find<toml::floating>(v, "key") = 2.71;
BOOST_TEST(toml::floating(2.71) == toml::find<toml::floating>(v, "key")); BOOST_TEST(toml::floating(2.71) == toml::find<toml::floating>(v, "key"));
const auto moved = toml::find<toml::floating>(std::move(v), "key");
BOOST_TEST(toml::floating(2.71) == moved);
} }
{ {
value_type v{{"key", "foo"}}; value_type v{{"key", "foo"}};
@@ -108,6 +171,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::string>(v, "key").str += "bar"; toml::find<toml::string>(v, "key").str += "bar";
BOOST_TEST(toml::string("foobar", toml::string_t::basic) == BOOST_TEST(toml::string("foobar", toml::string_t::basic) ==
toml::find<toml::string>(v, "key")); toml::find<toml::string>(v, "key"));
const auto moved = toml::find<toml::string>(std::move(v), "key");
BOOST_TEST(toml::string("foobar", toml::string_t::basic) == moved);
} }
{ {
value_type v{{"key", value_type("foo", toml::string_t::literal)}}; value_type v{{"key", value_type("foo", toml::string_t::literal)}};
@@ -117,6 +183,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::string>(v, "key").str += "bar"; toml::find<toml::string>(v, "key").str += "bar";
BOOST_TEST(toml::string("foobar", toml::string_t::literal) == BOOST_TEST(toml::string("foobar", toml::string_t::literal) ==
toml::find<toml::string>(v, "key")); toml::find<toml::string>(v, "key"));
const auto moved = toml::find<toml::string>(std::move(v), "key");
BOOST_TEST(toml::string("foobar", toml::string_t::literal) == moved);
} }
{ {
toml::local_date d(2018, toml::month_t::Apr, 22); toml::local_date d(2018, toml::month_t::Apr, 22);
@@ -126,6 +195,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::local_date>(v, "key").year = 2017; toml::find<toml::local_date>(v, "key").year = 2017;
d.year = 2017; d.year = 2017;
BOOST_CHECK(d == toml::find<toml::local_date>(v, "key")); BOOST_CHECK(d == toml::find<toml::local_date>(v, "key"));
const auto moved = toml::find<toml::local_date>(std::move(v), "key");
BOOST_CHECK(d == moved);
} }
{ {
toml::local_time t(12, 30, 45); toml::local_time t(12, 30, 45);
@@ -135,6 +207,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::local_time>(v, "key").hour = 9; toml::find<toml::local_time>(v, "key").hour = 9;
t.hour = 9; t.hour = 9;
BOOST_CHECK(t == toml::find<toml::local_time>(v, "key")); BOOST_CHECK(t == toml::find<toml::local_time>(v, "key"));
const auto moved = toml::find<toml::local_time>(std::move(v), "key");
BOOST_CHECK(t == moved);
} }
{ {
toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22),
@@ -145,6 +220,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::local_datetime>(v, "key").date.year = 2017; toml::find<toml::local_datetime>(v, "key").date.year = 2017;
dt.date.year = 2017; dt.date.year = 2017;
BOOST_CHECK(dt == toml::find<toml::local_datetime>(v, "key")); BOOST_CHECK(dt == toml::find<toml::local_datetime>(v, "key"));
const auto moved = toml::find<toml::local_datetime>(std::move(v), "key");
BOOST_CHECK(dt == moved);
} }
{ {
toml::offset_datetime dt(toml::local_datetime( toml::offset_datetime dt(toml::local_datetime(
@@ -156,6 +234,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
toml::find<toml::offset_datetime>(v, "key").date.year = 2017; toml::find<toml::offset_datetime>(v, "key").date.year = 2017;
dt.date.year = 2017; dt.date.year = 2017;
BOOST_CHECK(dt == toml::find<toml::offset_datetime>(v, "key")); BOOST_CHECK(dt == toml::find<toml::offset_datetime>(v, "key"));
const auto moved = toml::find<toml::offset_datetime>(std::move(v), "key");
BOOST_CHECK(dt == moved);
} }
{ {
typename value_type::array_type vec; typename value_type::array_type vec;
@@ -171,6 +252,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
const bool result2 = (vec == toml::find<typename value_type::array_type>(v, "key")); const bool result2 = (vec == toml::find<typename value_type::array_type>(v, "key"));
BOOST_CHECK(result2); BOOST_CHECK(result2);
const auto moved = toml::find<typename value_type::array_type>(std::move(v), "key");
const bool result3 = (vec == moved);
BOOST_CHECK(result3);
} }
{ {
typename value_type::table_type tab; typename value_type::table_type tab;
@@ -184,6 +269,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
tab["key3"] = value_type(123); tab["key3"] = value_type(123);
const bool result2 = (tab == toml::find<typename value_type::table_type>(v, "key")); const bool result2 = (tab == toml::find<typename value_type::table_type>(v, "key"));
BOOST_CHECK(result2); BOOST_CHECK(result2);
const auto moved = toml::find<typename value_type::table_type>(std::move(v), "key");
const bool result3 = (tab == moved);
BOOST_CHECK(result3);
} }
{ {
value_type v1(42); value_type v1(42);
@@ -193,6 +282,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
value_type v2(54); value_type v2(54);
toml::find(v, "key") = v2; toml::find(v, "key") = v2;
BOOST_CHECK(v2 == toml::find(v, "key")); BOOST_CHECK(v2 == toml::find(v, "key"));
const auto moved = toml::find(std::move(v), "key");
BOOST_CHECK(v2 == moved);
} }
} }
@@ -200,15 +292,16 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_integer_type, value_type, test_value_typ
{ {
{ {
value_type v{{"key", 42}}; value_type v{{"key", 42}};
BOOST_TEST(int(42) == toml::find<int >(v, "key")); BOOST_TEST(int(42) == toml::find<int >(v, "key"));
BOOST_TEST(short(42) == toml::find<short >(v, "key")); BOOST_TEST(short(42) == toml::find<short >(v, "key"));
BOOST_TEST(char(42) == toml::find<char >(v, "key")); BOOST_TEST(char(42) == toml::find<char >(v, "key"));
BOOST_TEST(unsigned(42) == toml::find<unsigned >(v, "key")); BOOST_TEST(unsigned(42) == toml::find<unsigned >(v, "key"));
BOOST_TEST(long(42) == toml::find<long >(v, "key")); BOOST_TEST(long(42) == toml::find<long >(v, "key"));
BOOST_TEST(std::int64_t(42) == toml::find<std::int64_t >(v, "key")); BOOST_TEST(std::int64_t(42) == toml::find<std::int64_t >(v, "key"));
BOOST_TEST(std::uint64_t(42) == toml::find<std::uint64_t>(v, "key")); BOOST_TEST(std::uint64_t(42) == toml::find<std::uint64_t>(v, "key"));
BOOST_TEST(std::int16_t(42) == toml::find<std::int16_t >(v, "key")); BOOST_TEST(std::int16_t(42) == toml::find<std::int16_t >(v, "key"));
BOOST_TEST(std::uint16_t(42) == toml::find<std::uint16_t>(v, "key")); BOOST_TEST(std::uint16_t(42) == toml::find<std::uint16_t>(v, "key"));
BOOST_TEST(std::uint16_t(42) == toml::find<std::uint16_t>(std::move(v), "key"));
} }
} }
@@ -219,6 +312,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_ty
BOOST_TEST(static_cast<float >(3.14) == toml::find<float >(v, "key")); BOOST_TEST(static_cast<float >(3.14) == toml::find<float >(v, "key"));
BOOST_TEST(static_cast<double >(3.14) == toml::find<double >(v, "key")); BOOST_TEST(static_cast<double >(3.14) == toml::find<double >(v, "key"));
BOOST_TEST(static_cast<long double>(3.14) == toml::find<long double>(v, "key")); BOOST_TEST(static_cast<long double>(3.14) == toml::find<long double>(v, "key"));
BOOST_TEST(static_cast<float >(3.14) == toml::find<float >(std::move(v), "key"));
} }
} }
@@ -236,6 +330,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_type
toml::find<std::string>(v, "key") += "bar"; toml::find<std::string>(v, "key") += "bar";
BOOST_TEST("foobar" == toml::find<std::string>(v, "key")); BOOST_TEST("foobar" == toml::find<std::string>(v, "key"));
} }
{
value_type v{{"key", toml::string("foo", toml::string_t::literal)}};
const auto moved = toml::find<std::string>(std::move(v), "key");
BOOST_TEST("foo" == moved);
}
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
{ {
@@ -292,6 +391,53 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array, value_type, test_value_types
BOOST_TEST(2.71 == pr.second); BOOST_TEST(2.71 == pr.second);
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array, value_type, test_value_types)
{
value_type v1{{"key", {42, 54, 69, 72}}};
value_type v2{{"key", {42, 54, 69, 72}}};
value_type v3{{"key", {42, 54, 69, 72}}};
value_type v4{{"key", {42, 54, 69, 72}}};
value_type v5{{"key", {42, 54, 69, 72}}};
const std::vector<int> vec = toml::find<std::vector<int>>(std::move(v1), "key");
const std::list<short> lst = toml::find<std::list<short>>(std::move(v2), "key");
const std::deque<std::int64_t> deq = toml::find<std::deque<std::int64_t>>(std::move(v3), "key");
BOOST_TEST(42 == vec.at(0));
BOOST_TEST(54 == vec.at(1));
BOOST_TEST(69 == vec.at(2));
BOOST_TEST(72 == vec.at(3));
std::list<short>::const_iterator iter = lst.begin();
BOOST_TEST(static_cast<short>(42) == *(iter++));
BOOST_TEST(static_cast<short>(54) == *(iter++));
BOOST_TEST(static_cast<short>(69) == *(iter++));
BOOST_TEST(static_cast<short>(72) == *(iter++));
BOOST_TEST(static_cast<std::int64_t>(42) == deq.at(0));
BOOST_TEST(static_cast<std::int64_t>(54) == deq.at(1));
BOOST_TEST(static_cast<std::int64_t>(69) == deq.at(2));
BOOST_TEST(static_cast<std::int64_t>(72) == deq.at(3));
std::array<int, 4> ary = toml::find<std::array<int, 4>>(std::move(v4), "key");
BOOST_TEST(static_cast<int>(42) == ary.at(0));
BOOST_TEST(static_cast<int>(54) == ary.at(1));
BOOST_TEST(static_cast<int>(69) == ary.at(2));
BOOST_TEST(static_cast<int>(72) == ary.at(3));
std::tuple<int, short, unsigned, long> tpl =
toml::find<std::tuple<int, short, unsigned, long>>(std::move(v5), "key");
BOOST_TEST(static_cast<int >(42) == std::get<0>(tpl));
BOOST_TEST(static_cast<short >(54) == std::get<1>(tpl));
BOOST_TEST(static_cast<unsigned>(69) == std::get<2>(tpl));
BOOST_TEST(static_cast<long >(72) == std::get<3>(tpl));
value_type p{{"key", {3.14, 2.71}}};
std::pair<double, double> pr = toml::find<std::pair<double, double> >(std::move(p), "key");
BOOST_TEST(3.14 == pr.first);
BOOST_TEST(2.71 == pr.second);
}
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_value_types)
{ {
value_type v1{42, 54, 69, 72}; value_type v1{42, 54, 69, 72};
@@ -323,62 +469,153 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_va
BOOST_TEST(std::get<1>(t).at(2) == "baz"); BOOST_TEST(std::get<1>(t).at(2) == "baz");
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_move_toml_array_of_array, value_type, test_value_types)
{
value_type a1{42, 54, 69, 72};
value_type a2{"foo", "bar", "baz"};
value_type v1{{"key", {a1, a2}}};
value_type v2{{"key", {a1, a2}}};
std::pair<std::vector<int>, std::vector<std::string>> p =
toml::find<std::pair<std::vector<int>, std::vector<std::string>>>(std::move(v1), "key");
BOOST_TEST(p.first.at(0) == 42);
BOOST_TEST(p.first.at(1) == 54);
BOOST_TEST(p.first.at(2) == 69);
BOOST_TEST(p.first.at(3) == 72);
BOOST_TEST(p.second.at(0) == "foo");
BOOST_TEST(p.second.at(1) == "bar");
BOOST_TEST(p.second.at(2) == "baz");
std::tuple<std::vector<int>, std::vector<std::string>> t =
toml::find<std::tuple<std::vector<int>, std::vector<std::string>>>(std::move(v2), "key");
BOOST_TEST(std::get<0>(t).at(0) == 42);
BOOST_TEST(std::get<0>(t).at(1) == 54);
BOOST_TEST(std::get<0>(t).at(2) == 69);
BOOST_TEST(std::get<0>(t).at(3) == 72);
BOOST_TEST(std::get<1>(t).at(0) == "foo");
BOOST_TEST(std::get<1>(t).at(1) == "bar");
BOOST_TEST(std::get<1>(t).at(2) == "baz");
}
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_table, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_table, value_type, test_value_types)
{ {
value_type v1{{"key", { {
{"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} value_type v1{{"key", {
}}}; {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4}
const auto v = toml::find<std::map<std::string, int>>(v1, "key"); }}};
BOOST_TEST(v.at("key1") == 1); const auto v = toml::find<std::map<std::string, int>>(v1, "key");
BOOST_TEST(v.at("key2") == 2); BOOST_TEST(v.at("key1") == 1);
BOOST_TEST(v.at("key3") == 3); BOOST_TEST(v.at("key2") == 2);
BOOST_TEST(v.at("key4") == 4); BOOST_TEST(v.at("key3") == 3);
BOOST_TEST(v.at("key4") == 4);
}
{
value_type v1{{"key", {
{"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4}
}}};
const auto v = toml::find<std::map<std::string, int>>(std::move(v1), "key");
BOOST_TEST(v.at("key1") == 1);
BOOST_TEST(v.at("key2") == 2);
BOOST_TEST(v.at("key3") == 3);
BOOST_TEST(v.at("key4") == 4);
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_types)
{ {
value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}}; {
const auto date = std::chrono::system_clock::to_time_t( value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}};
toml::find<std::chrono::system_clock::time_point>(v1, "key")); const auto date = std::chrono::system_clock::to_time_t(
toml::find<std::chrono::system_clock::time_point>(v1, "key"));
std::tm t; std::tm t;
t.tm_year = 2018 - 1900; t.tm_year = 2018 - 1900;
t.tm_mon = 4 - 1; t.tm_mon = 4 - 1;
t.tm_mday = 1; t.tm_mday = 1;
t.tm_hour = 0; t.tm_hour = 0;
t.tm_min = 0; t.tm_min = 0;
t.tm_sec = 0; t.tm_sec = 0;
t.tm_isdst = -1; t.tm_isdst = -1;
const auto c = std::mktime(&t); const auto c = std::mktime(&t);
BOOST_TEST(c == date); BOOST_TEST(c == date);
}
{
value_type v1{{"key", toml::local_date{2018, toml::month_t::Apr, 1}}};
const auto date = std::chrono::system_clock::to_time_t(
toml::find<std::chrono::system_clock::time_point>(std::move(v1), "key"));
std::tm t;
t.tm_year = 2018 - 1900;
t.tm_mon = 4 - 1;
t.tm_mday = 1;
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = -1;
const auto c = std::mktime(&t);
BOOST_TEST(c == date);
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_time, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_time, value_type, test_value_types)
{ {
value_type v1{{"key", toml::local_time{12, 30, 45}}}; {
const auto time = toml::find<std::chrono::seconds>(v1, "key"); value_type v1{{"key", toml::local_time{12, 30, 45}}};
BOOST_CHECK(time == std::chrono::hours(12) + const auto time = toml::find<std::chrono::seconds>(v1, "key");
std::chrono::minutes(30) + std::chrono::seconds(45)); BOOST_CHECK(time == std::chrono::hours(12) +
std::chrono::minutes(30) + std::chrono::seconds(45));
}
{
value_type v1{{"key", toml::local_time{12, 30, 45}}};
const auto time = toml::find<std::chrono::seconds>(std::move(v1), "key");
BOOST_CHECK(time == std::chrono::hours(12) +
std::chrono::minutes(30) + std::chrono::seconds(45));
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_value_types)
{ {
value_type v1{{"key", toml::local_datetime( {
toml::local_date{2018, toml::month_t::Apr, 1}, value_type v1{{"key", toml::local_datetime(
toml::local_time{12, 30, 45})}}; toml::local_date{2018, toml::month_t::Apr, 1},
toml::local_time{12, 30, 45})}};
const auto date = std::chrono::system_clock::to_time_t( const auto date = std::chrono::system_clock::to_time_t(
toml::find<std::chrono::system_clock::time_point>(v1, "key")); toml::find<std::chrono::system_clock::time_point>(v1, "key"));
std::tm t; std::tm t;
t.tm_year = 2018 - 1900; t.tm_year = 2018 - 1900;
t.tm_mon = 4 - 1; t.tm_mon = 4 - 1;
t.tm_mday = 1; t.tm_mday = 1;
t.tm_hour = 12; t.tm_hour = 12;
t.tm_min = 30; t.tm_min = 30;
t.tm_sec = 45; t.tm_sec = 45;
t.tm_isdst = -1; t.tm_isdst = -1;
const auto c = std::mktime(&t); const auto c = std::mktime(&t);
BOOST_TEST(c == date); BOOST_TEST(c == date);
}
{
value_type v1{{"key", toml::local_datetime(
toml::local_date{2018, toml::month_t::Apr, 1},
toml::local_time{12, 30, 45})}};
const auto date = std::chrono::system_clock::to_time_t(
toml::find<std::chrono::system_clock::time_point>(std::move(v1), "key"));
std::tm t;
t.tm_year = 2018 - 1900;
t.tm_mon = 4 - 1;
t.tm_mday = 1;
t.tm_hour = 12;
t.tm_min = 30;
t.tm_sec = 45;
t.tm_isdst = -1;
const auto c = std::mktime(&t);
BOOST_TEST(c == date);
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types)
@@ -428,5 +665,28 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_va
BOOST_TEST(tm.tm_min == 30); BOOST_TEST(tm.tm_min == 30);
BOOST_TEST(tm.tm_sec == 0); BOOST_TEST(tm.tm_sec == 0);
} }
{
value_type v1{{"key", toml::offset_datetime(
toml::local_date{2018, toml::month_t::Apr, 1},
toml::local_time{12, 30, 0},
toml::time_offset{-8, 0})}};
// 2018-04-01T12:30:00-08:00
// == 2018-04-01T20:30:00Z
const auto date = toml::find<std::chrono::system_clock::time_point>(std::move(v1), "key");
const auto timet = std::chrono::system_clock::to_time_t(date);
// get time_t as gmtime (2018-04-01T03:30:00Z)
const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe!
BOOST_CHECK(tmp);
const auto tm = *tmp;
BOOST_TEST(tm.tm_year + 1900 == 2018);
BOOST_TEST(tm.tm_mon + 1 == 4);
BOOST_TEST(tm.tm_mday == 1);
BOOST_TEST(tm.tm_hour == 20);
BOOST_TEST(tm.tm_min == 30);
BOOST_TEST(tm.tm_sec == 0);
}
} }

View File

@@ -121,6 +121,55 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types)
} }
#undef TOML11_TEST_FIND_OR_EXACT #undef TOML11_TEST_FIND_OR_EXACT
#define TOML11_TEST_FIND_OR_MOVE(toml_type, init_expr, opt_expr) \
{ \
using namespace test; \
const toml::toml_type init init_expr ; \
toml::toml_type opt opt_expr ; \
value_type v{{"key", init}}; \
BOOST_TEST(init != opt); \
const auto moved = toml::find_or(std::move(v), "key", std::move(opt));\
BOOST_TEST(init == moved); \
} \
/**/
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_move, value_type, test_value_types)
{
TOML11_TEST_FIND_OR_MOVE(boolean, ( true), (false))
TOML11_TEST_FIND_OR_MOVE(integer, ( 42), ( 54))
TOML11_TEST_FIND_OR_MOVE(floating, ( 3.14), ( 2.71))
TOML11_TEST_FIND_OR_MOVE(string, ("foo"), ("bar"))
TOML11_TEST_FIND_OR_MOVE(local_time, (12, 30, 45), (6, 0, 30))
TOML11_TEST_FIND_OR_MOVE(local_date, (2019, toml::month_t::Apr, 1),
(1999, toml::month_t::Jan, 2))
TOML11_TEST_FIND_OR_MOVE(local_datetime,
(toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)),
(toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30))
)
TOML11_TEST_FIND_OR_MOVE(offset_datetime,
(toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)),
(toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0))
)
{
typename value_type::array_type init{1,2,3,4,5};
typename value_type::array_type opt {6,7,8,9,10};
value_type v{{"key", init}};
BOOST_TEST(init != opt);
const auto moved = toml::find_or(std::move(v), "key", std::move(opt));
BOOST_TEST(init == moved);
}
{
typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}};
value_type v{{"key", init}};
BOOST_TEST(init != opt);
const auto moved = toml::find_or(std::move(v), "key", std::move(opt));
BOOST_TEST(init == moved);
}
}
#undef TOML11_TEST_FIND_OR_MOVE
#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\ #define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\
{ \ { \
using namespace test; \ using namespace test; \
@@ -304,10 +353,20 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_type
BOOST_AUTO_TEST_CASE(test_find_or_integer) BOOST_AUTO_TEST_CASE(test_find_or_integer)
{ {
{ {
toml::value v = toml::table{{"num", 42}}; toml::value v{{"num", 42}};
BOOST_TEST(42u == toml::find_or(v, "num", 0u)); BOOST_TEST(42u == toml::find_or(v, "num", 0u));
BOOST_TEST(0u == toml::find_or(v, "foo", 0u)); BOOST_TEST(0u == toml::find_or(v, "foo", 0u));
} }
{
toml::value v{{"num", 42}};
const auto moved = toml::find_or(std::move(v), "num", 0u);
BOOST_TEST(42u == moved);
}
{
toml::value v{{"num", 42}};
const auto moved = toml::find_or(std::move(v), "foo", 0u);
BOOST_TEST(0u == moved);
}
} }
BOOST_AUTO_TEST_CASE(test_find_or_floating) BOOST_AUTO_TEST_CASE(test_find_or_floating)
@@ -318,6 +377,14 @@ BOOST_AUTO_TEST_CASE(test_find_or_floating)
BOOST_TEST(2.71f == toml::find_or(v1, "key", 2.71f)); BOOST_TEST(2.71f == toml::find_or(v1, "key", 2.71f));
BOOST_TEST(static_cast<float>(double(3.14)) == toml::find_or(v2, "key", 2.71f)); BOOST_TEST(static_cast<float>(double(3.14)) == toml::find_or(v2, "key", 2.71f));
} }
{
toml::value v1{{"key", 42}};
toml::value v2{{"key", 3.14}};
const auto moved1 = toml::find_or(std::move(v1), "key", 2.71f);
const auto moved2 = toml::find_or(std::move(v2), "key", 2.71f);
BOOST_TEST(2.71f == moved1);
BOOST_TEST(static_cast<float>(double(3.14)) == moved2);
}
} }
BOOST_AUTO_TEST_CASE(test_find_or_string) BOOST_AUTO_TEST_CASE(test_find_or_string)
@@ -345,6 +412,32 @@ BOOST_AUTO_TEST_CASE(test_find_or_string)
s1 = "bazqux"; // restoring moved value s1 = "bazqux"; // restoring moved value
BOOST_TEST("bazqux" == toml::find_or(std::move(v2), "key", std::move(s1))); BOOST_TEST("bazqux" == toml::find_or(std::move(v2), "key", std::move(s1)));
} }
{
toml::value v1 = toml::table{{"key", "foobar"}};
toml::value v2 = toml::table{{"key", 42}};
std::string s1("bazqux");
const auto moved1 = toml::find_or(std::move(v1), "key", s1);
const auto moved2 = toml::find_or(std::move(v2), "key", s1);
BOOST_TEST("foobar" == moved1);
BOOST_TEST("bazqux" == moved2);
}
{
toml::value v1 = toml::table{{"key", "foobar"}};
toml::value v2 = toml::table{{"key", 42}};
std::string s1("bazqux");
std::string s2("bazqux");
const auto moved1 = toml::find_or(std::move(v1), "key", std::move(s1));
const auto moved2 = toml::find_or(std::move(v2), "key", std::move(s2));
BOOST_TEST("foobar" == moved1);
BOOST_TEST("bazqux" == moved2);
}
// string literal // string literal
{ {
toml::value v1 = toml::table{{"key", "foobar"}}; toml::value v1 = toml::table{{"key", "foobar"}};
@@ -357,6 +450,28 @@ BOOST_AUTO_TEST_CASE(test_find_or_string)
BOOST_TEST("foobar" == toml::find_or(v1, "key", lit)); BOOST_TEST("foobar" == toml::find_or(v1, "key", lit));
BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit)); BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit));
} }
{
toml::value v1 = toml::table{{"key", "foobar"}};
toml::value v2 = toml::table{{"key",42}};
const auto moved1 = toml::find_or(std::move(v1), "key", "bazqux");
const auto moved2 = toml::find_or(std::move(v2), "key", "bazqux");
BOOST_TEST("foobar" == moved1);
BOOST_TEST("bazqux" == moved2);
}
{
toml::value v1 = toml::table{{"key", "foobar"}};
toml::value v2 = toml::table{{"key",42}};
const char* lit = "bazqux";
const auto moved1 = toml::find_or(std::move(v1), "key", lit);
const auto moved2 = toml::find_or(std::move(v2), "key", lit);
BOOST_TEST("foobar" == moved1);
BOOST_TEST("bazqux" == moved2);
}
} }
BOOST_AUTO_TEST_CASE(test_find_or_map) BOOST_AUTO_TEST_CASE(test_find_or_map)
@@ -377,7 +492,7 @@ BOOST_AUTO_TEST_CASE(test_find_or_map)
BOOST_TEST(key.at("key") == "value"); BOOST_TEST(key.at("key") == "value");
} }
{ {
const toml::value v1{ toml::value v1{
{"key", {{"key", "value"}}} {"key", {{"key", "value"}}}
}; };
@@ -390,4 +505,35 @@ BOOST_AUTO_TEST_CASE(test_find_or_map)
BOOST_TEST(key.size() == 1u); BOOST_TEST(key.size() == 1u);
BOOST_TEST(key.at("key") == "value"); BOOST_TEST(key.at("key") == "value");
} }
{
toml::value v1{
{"key", {{"key", "value"}}}
};
toml::value v2(v1);
const auto key = toml::find_or(std::move(v1), "key", map_type{});
const auto key2 = toml::find_or(std::move(v2), "key2", map_type{});
BOOST_TEST(!key.empty());
BOOST_TEST(key2.empty());
BOOST_TEST(key.size() == 1u);
BOOST_TEST(key.at("key") == "value");
}
{
toml::value v1{
{"key", {{"key", "value"}}}
};
toml::value v2(v1);
const auto key = toml::find_or<map_type>(std::move(v1), "key", map_type{});
const auto key2 = toml::find_or<map_type>(std::move(v2), "key2", map_type{});
BOOST_TEST(!key.empty());
BOOST_TEST(key2.empty());
BOOST_TEST(key.size() == 1u);
BOOST_TEST(key.at("key") == "value");
}
} }

View File

@@ -31,6 +31,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::boolean>(v) = false; toml::get<toml::boolean>(v) = false;
BOOST_TEST(false == toml::get<toml::boolean>(v)); BOOST_TEST(false == toml::get<toml::boolean>(v));
toml::boolean x = toml::get<toml::boolean>(std::move(v));
BOOST_TEST(false == x);
} }
{ {
value_type v(42); value_type v(42);
@@ -38,6 +41,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::integer>(v) = 54; toml::get<toml::integer>(v) = 54;
BOOST_TEST(toml::integer(54) == toml::get<toml::integer>(v)); BOOST_TEST(toml::integer(54) == toml::get<toml::integer>(v));
toml::integer x = toml::get<toml::integer>(std::move(v));
BOOST_TEST(toml::integer(54) == x);
} }
{ {
value_type v(3.14); value_type v(3.14);
@@ -45,6 +51,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::floating>(v) = 2.71; toml::get<toml::floating>(v) = 2.71;
BOOST_TEST(toml::floating(2.71) == toml::get<toml::floating>(v)); BOOST_TEST(toml::floating(2.71) == toml::get<toml::floating>(v));
toml::floating x = toml::get<toml::floating>(std::move(v));
BOOST_TEST(toml::floating(2.71) == x);
} }
{ {
value_type v("foo"); value_type v("foo");
@@ -54,6 +63,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::string>(v).str += "bar"; toml::get<toml::string>(v).str += "bar";
BOOST_TEST(toml::string("foobar", toml::string_t::basic) == BOOST_TEST(toml::string("foobar", toml::string_t::basic) ==
toml::get<toml::string>(v)); toml::get<toml::string>(v));
toml::string x = toml::get<toml::string>(std::move(v));
BOOST_TEST(toml::string("foobar") == x);
} }
{ {
value_type v("foo", toml::string_t::literal); value_type v("foo", toml::string_t::literal);
@@ -63,6 +75,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::string>(v).str += "bar"; toml::get<toml::string>(v).str += "bar";
BOOST_TEST(toml::string("foobar", toml::string_t::literal) == BOOST_TEST(toml::string("foobar", toml::string_t::literal) ==
toml::get<toml::string>(v)); toml::get<toml::string>(v));
toml::string x = toml::get<toml::string>(std::move(v));
BOOST_TEST(toml::string("foobar", toml::string_t::literal) == x);
} }
{ {
toml::local_date d(2018, toml::month_t::Apr, 22); toml::local_date d(2018, toml::month_t::Apr, 22);
@@ -72,6 +87,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::local_date>(v).year = 2017; toml::get<toml::local_date>(v).year = 2017;
d.year = 2017; d.year = 2017;
BOOST_TEST(d == toml::get<toml::local_date>(v)); BOOST_TEST(d == toml::get<toml::local_date>(v));
toml::local_date x = toml::get<toml::local_date>(std::move(v));
BOOST_TEST(d == x);
} }
{ {
toml::local_time t(12, 30, 45); toml::local_time t(12, 30, 45);
@@ -81,6 +99,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::local_time>(v).hour = 9; toml::get<toml::local_time>(v).hour = 9;
t.hour = 9; t.hour = 9;
BOOST_TEST(t == toml::get<toml::local_time>(v)); BOOST_TEST(t == toml::get<toml::local_time>(v));
toml::local_time x = toml::get<toml::local_time>(std::move(v));
BOOST_TEST(t == x);
} }
{ {
toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22),
@@ -91,6 +112,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::local_datetime>(v).date.year = 2017; toml::get<toml::local_datetime>(v).date.year = 2017;
dt.date.year = 2017; dt.date.year = 2017;
BOOST_TEST(dt == toml::get<toml::local_datetime>(v)); BOOST_TEST(dt == toml::get<toml::local_datetime>(v));
toml::local_datetime x = toml::get<toml::local_datetime>(std::move(v));
BOOST_TEST(dt == x);
} }
{ {
toml::offset_datetime dt(toml::local_datetime( toml::offset_datetime dt(toml::local_datetime(
@@ -102,6 +126,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<toml::offset_datetime>(v).date.year = 2017; toml::get<toml::offset_datetime>(v).date.year = 2017;
dt.date.year = 2017; dt.date.year = 2017;
BOOST_TEST(dt == toml::get<toml::offset_datetime>(v)); BOOST_TEST(dt == toml::get<toml::offset_datetime>(v));
toml::offset_datetime x = toml::get<toml::offset_datetime>(std::move(v));
BOOST_TEST(dt == x);
} }
{ {
using array_type = typename value_type::array_type; using array_type = typename value_type::array_type;
@@ -114,6 +141,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<array_type>(v).push_back(value_type(123)); toml::get<array_type>(v).push_back(value_type(123));
vec.push_back(value_type(123)); vec.push_back(value_type(123));
BOOST_TEST(vec == toml::get<array_type>(v)); BOOST_TEST(vec == toml::get<array_type>(v));
array_type x = toml::get<array_type>(std::move(v));
BOOST_TEST(vec == x);
} }
{ {
using table_type = typename value_type::table_type; using table_type = typename value_type::table_type;
@@ -126,6 +156,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
toml::get<table_type>(v)["key3"] = value_type(123); toml::get<table_type>(v)["key3"] = value_type(123);
tab["key3"] = value_type(123); tab["key3"] = value_type(123);
BOOST_TEST(tab == toml::get<table_type>(v)); BOOST_TEST(tab == toml::get<table_type>(v));
table_type x = toml::get<table_type>(std::move(v));
BOOST_TEST(tab == x);
} }
{ {
value_type v1(42); value_type v1(42);
@@ -134,6 +167,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
value_type v2(54); value_type v2(54);
toml::get<value_type>(v1) = v2; toml::get<value_type>(v1) = v2;
BOOST_TEST(v2 == toml::get<value_type>(v1)); BOOST_TEST(v2 == toml::get<value_type>(v1));
value_type x = toml::get<value_type>(std::move(v1));
BOOST_TEST(v2 == x);
} }
} }
@@ -150,6 +186,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_integer_type, value_type, test_value_type
BOOST_TEST(std::uint64_t(42) == toml::get<std::uint64_t>(v)); BOOST_TEST(std::uint64_t(42) == toml::get<std::uint64_t>(v));
BOOST_TEST(std::int16_t(42) == toml::get<std::int16_t >(v)); BOOST_TEST(std::int16_t(42) == toml::get<std::int16_t >(v));
BOOST_TEST(std::uint16_t(42) == toml::get<std::uint16_t>(v)); BOOST_TEST(std::uint16_t(42) == toml::get<std::uint16_t>(v));
BOOST_TEST(std::uint16_t(42) == toml::get<std::uint16_t>(std::move(v)));
} }
} }
@@ -160,6 +198,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_floating_type, value_type, test_value_typ
BOOST_TEST(static_cast<float >(3.14) == toml::get<float >(v)); BOOST_TEST(static_cast<float >(3.14) == toml::get<float >(v));
BOOST_TEST(static_cast<double >(3.14) == toml::get<double >(v)); BOOST_TEST(static_cast<double >(3.14) == toml::get<double >(v));
BOOST_TEST(static_cast<long double>(3.14) == toml::get<long double>(v)); BOOST_TEST(static_cast<long double>(3.14) == toml::get<long double>(v));
BOOST_TEST(3.14f == toml::get<float>(std::move(v)));
} }
} }
@@ -170,12 +210,18 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types
BOOST_TEST("foo" == toml::get<std::string>(v)); BOOST_TEST("foo" == toml::get<std::string>(v));
toml::get<std::string>(v) += "bar"; toml::get<std::string>(v) += "bar";
BOOST_TEST("foobar" == toml::get<std::string>(v)); BOOST_TEST("foobar" == toml::get<std::string>(v));
const auto x = toml::get<std::string>(std::move(v));
BOOST_TEST("foobar" == x);
} }
{ {
value_type v("foo", toml::string_t::literal); value_type v("foo", toml::string_t::literal);
BOOST_TEST("foo" == toml::get<std::string>(v)); BOOST_TEST("foo" == toml::get<std::string>(v));
toml::get<std::string>(v) += "bar"; toml::get<std::string>(v) += "bar";
BOOST_TEST("foobar" == toml::get<std::string>(v)); BOOST_TEST("foobar" == toml::get<std::string>(v));
const auto x = toml::get<std::string>(std::move(v));
BOOST_TEST("foobar" == x);
} }
#if __cplusplus >= 201703L #if __cplusplus >= 201703L
@@ -192,92 +238,176 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array, value_type, test_value_types)
{ {
const value_type v{42, 54, 69, 72}; {
const value_type v{42, 54, 69, 72};
const std::vector<int> vec = toml::get<std::vector<int>>(v); const std::vector<int> vec = toml::get<std::vector<int>>(v);
const std::list<short> lst = toml::get<std::list<short>>(v); const std::list<short> lst = toml::get<std::list<short>>(v);
const std::deque<std::int64_t> deq = toml::get<std::deque<std::int64_t>>(v); const std::deque<std::int64_t> deq = toml::get<std::deque<std::int64_t>>(v);
BOOST_TEST(42 == vec.at(0)); BOOST_TEST(42 == vec.at(0));
BOOST_TEST(54 == vec.at(1)); BOOST_TEST(54 == vec.at(1));
BOOST_TEST(69 == vec.at(2)); BOOST_TEST(69 == vec.at(2));
BOOST_TEST(72 == vec.at(3)); BOOST_TEST(72 == vec.at(3));
std::list<short>::const_iterator iter = lst.begin(); std::list<short>::const_iterator iter = lst.begin();
BOOST_TEST(static_cast<short>(42) == *(iter++)); BOOST_TEST(static_cast<short>(42) == *(iter++));
BOOST_TEST(static_cast<short>(54) == *(iter++)); BOOST_TEST(static_cast<short>(54) == *(iter++));
BOOST_TEST(static_cast<short>(69) == *(iter++)); BOOST_TEST(static_cast<short>(69) == *(iter++));
BOOST_TEST(static_cast<short>(72) == *(iter++)); BOOST_TEST(static_cast<short>(72) == *(iter++));
BOOST_TEST(static_cast<std::int64_t>(42) == deq.at(0)); BOOST_TEST(static_cast<std::int64_t>(42) == deq.at(0));
BOOST_TEST(static_cast<std::int64_t>(54) == deq.at(1)); BOOST_TEST(static_cast<std::int64_t>(54) == deq.at(1));
BOOST_TEST(static_cast<std::int64_t>(69) == deq.at(2)); BOOST_TEST(static_cast<std::int64_t>(69) == deq.at(2));
BOOST_TEST(static_cast<std::int64_t>(72) == deq.at(3)); BOOST_TEST(static_cast<std::int64_t>(72) == deq.at(3));
std::array<int, 4> ary = toml::get<std::array<int, 4>>(v); std::array<int, 4> ary = toml::get<std::array<int, 4>>(v);
BOOST_TEST(static_cast<int>(42) == ary.at(0)); BOOST_TEST(static_cast<int>(42) == ary.at(0));
BOOST_TEST(static_cast<int>(54) == ary.at(1)); BOOST_TEST(static_cast<int>(54) == ary.at(1));
BOOST_TEST(static_cast<int>(69) == ary.at(2)); BOOST_TEST(static_cast<int>(69) == ary.at(2));
BOOST_TEST(static_cast<int>(72) == ary.at(3)); BOOST_TEST(static_cast<int>(72) == ary.at(3));
std::tuple<int, short, unsigned, long> tpl = std::tuple<int, short, unsigned, long> tpl =
toml::get<std::tuple<int, short, unsigned, long>>(v); toml::get<std::tuple<int, short, unsigned, long>>(v);
BOOST_TEST(static_cast<int >(42) == std::get<0>(tpl)); BOOST_TEST(static_cast<int >(42) == std::get<0>(tpl));
BOOST_TEST(static_cast<short >(54) == std::get<1>(tpl)); BOOST_TEST(static_cast<short >(54) == std::get<1>(tpl));
BOOST_TEST(static_cast<unsigned>(69) == std::get<2>(tpl)); BOOST_TEST(static_cast<unsigned>(69) == std::get<2>(tpl));
BOOST_TEST(static_cast<long >(72) == std::get<3>(tpl)); BOOST_TEST(static_cast<long >(72) == std::get<3>(tpl));
const value_type p{3.14, 2.71}; const value_type p{3.14, 2.71};
std::pair<double, double> pr = toml::get<std::pair<double, double> >(p); std::pair<double, double> pr = toml::get<std::pair<double, double> >(p);
BOOST_TEST(3.14 == pr.first); BOOST_TEST(3.14 == pr.first);
BOOST_TEST(2.71 == pr.second); BOOST_TEST(2.71 == pr.second);
}
{
value_type v{42, 54, 69, 72};
const std::vector<int> vec = toml::get<std::vector<int>>(std::move(v));
BOOST_TEST(42 == vec.at(0));
BOOST_TEST(54 == vec.at(1));
BOOST_TEST(69 == vec.at(2));
BOOST_TEST(72 == vec.at(3));
}
{
value_type v{42, 54, 69, 72};
const std::deque<int> deq = toml::get<std::deque<int>>(std::move(v));
BOOST_TEST(42 == deq.at(0));
BOOST_TEST(54 == deq.at(1));
BOOST_TEST(69 == deq.at(2));
BOOST_TEST(72 == deq.at(3));
}
{
value_type v{42, 54, 69, 72};
const std::list<int> lst = toml::get<std::list<int>>(std::move(v));
std::list<int>::const_iterator iter = lst.begin();
BOOST_TEST(42 == *(iter++));
BOOST_TEST(54 == *(iter++));
BOOST_TEST(69 == *(iter++));
BOOST_TEST(72 == *(iter++));
}
{
value_type v{42, 54, 69, 72};
std::array<int, 4> ary = toml::get<std::array<int, 4>>(std::move(v));
BOOST_TEST(static_cast<int>(42) == ary.at(0));
BOOST_TEST(static_cast<int>(54) == ary.at(1));
BOOST_TEST(static_cast<int>(69) == ary.at(2));
BOOST_TEST(static_cast<int>(72) == ary.at(3));
}
{
value_type v{42, 54, 69, 72};
std::tuple<int, short, unsigned, long> tpl =
toml::get<std::tuple<int, short, unsigned, long>>(std::move(v));
BOOST_TEST(static_cast<int >(42) == std::get<0>(tpl));
BOOST_TEST(static_cast<short >(54) == std::get<1>(tpl));
BOOST_TEST(static_cast<unsigned>(69) == std::get<2>(tpl));
BOOST_TEST(static_cast<long >(72) == std::get<3>(tpl));
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array_of_array, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array_of_array, value_type, test_value_types)
{ {
const value_type v1{42, 54, 69, 72}; {
const value_type v2{"foo", "bar", "baz"}; const value_type v1{42, 54, 69, 72};
const value_type v{v1, v2}; const value_type v2{"foo", "bar", "baz"};
const value_type v{v1, v2};
std::pair<std::vector<int>, std::vector<std::string>> p = std::pair<std::vector<int>, std::vector<std::string>> p =
toml::get<std::pair<std::vector<int>, std::vector<std::string>>>(v); toml::get<std::pair<std::vector<int>, std::vector<std::string>>>(v);
BOOST_TEST(p.first.at(0) == 42); BOOST_TEST(p.first.size() == 4u);
BOOST_TEST(p.first.at(1) == 54); BOOST_TEST(p.first.at(0) == 42);
BOOST_TEST(p.first.at(2) == 69); BOOST_TEST(p.first.at(1) == 54);
BOOST_TEST(p.first.at(3) == 72); BOOST_TEST(p.first.at(2) == 69);
BOOST_TEST(p.first.at(3) == 72);
BOOST_TEST(p.second.at(0) == "foo"); BOOST_TEST(p.second.size() == 3u);
BOOST_TEST(p.second.at(1) == "bar"); BOOST_TEST(p.second.at(0) == "foo");
BOOST_TEST(p.second.at(2) == "baz"); BOOST_TEST(p.second.at(1) == "bar");
BOOST_TEST(p.second.at(2) == "baz");
std::tuple<std::vector<int>, std::vector<std::string>> t = std::tuple<std::vector<int>, std::vector<std::string>> t =
toml::get<std::tuple<std::vector<int>, std::vector<std::string>>>(v); toml::get<std::tuple<std::vector<int>, std::vector<std::string>>>(v);
BOOST_TEST(std::get<0>(t).at(0) == 42); BOOST_TEST(std::get<0>(t).at(0) == 42);
BOOST_TEST(std::get<0>(t).at(1) == 54); BOOST_TEST(std::get<0>(t).at(1) == 54);
BOOST_TEST(std::get<0>(t).at(2) == 69); BOOST_TEST(std::get<0>(t).at(2) == 69);
BOOST_TEST(std::get<0>(t).at(3) == 72); BOOST_TEST(std::get<0>(t).at(3) == 72);
BOOST_TEST(std::get<1>(t).at(0) == "foo"); BOOST_TEST(std::get<1>(t).at(0) == "foo");
BOOST_TEST(std::get<1>(t).at(1) == "bar"); BOOST_TEST(std::get<1>(t).at(1) == "bar");
BOOST_TEST(std::get<1>(t).at(2) == "baz"); BOOST_TEST(std::get<1>(t).at(2) == "baz");
}
{
const value_type v1{42, 54, 69, 72};
const value_type v2{"foo", "bar", "baz"};
value_type v{v1, v2};
std::pair<std::vector<int>, std::vector<std::string>> p =
toml::get<std::pair<std::vector<int>, std::vector<std::string>>>(std::move(v));
BOOST_TEST(p.first.size() == 4u);
BOOST_TEST(p.first.at(0) == 42);
BOOST_TEST(p.first.at(1) == 54);
BOOST_TEST(p.first.at(2) == 69);
BOOST_TEST(p.first.at(3) == 72);
BOOST_TEST(p.second.size() == 3u);
BOOST_TEST(p.second.at(0) == "foo");
BOOST_TEST(p.second.at(1) == "bar");
BOOST_TEST(p.second.at(2) == "baz");
}
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_table, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_table, value_type, test_value_types)
{ {
const value_type v1{ {
{"key1", 1}, const value_type v1{
{"key2", 2}, {"key1", 1},
{"key3", 3}, {"key2", 2},
{"key4", 4} {"key3", 3},
}; {"key4", 4}
};
const auto v = toml::get<std::map<std::string, int>>(v1);
BOOST_TEST(v.at("key1") == 1);
BOOST_TEST(v.at("key2") == 2);
BOOST_TEST(v.at("key3") == 3);
BOOST_TEST(v.at("key4") == 4);
}
{
value_type v1{
{"key1", 1},
{"key2", 2},
{"key3", 3},
{"key4", 4}
};
const auto v = toml::get<std::map<std::string, int>>(std::move(v1));
BOOST_TEST(v.at("key1") == 1);
BOOST_TEST(v.at("key2") == 2);
BOOST_TEST(v.at("key3") == 3);
BOOST_TEST(v.at("key4") == 4);
}
const auto v = toml::get<std::map<std::string, int>>(v1);
BOOST_TEST(v.at("key1") == 1);
BOOST_TEST(v.at("key2") == 2);
BOOST_TEST(v.at("key3") == 3);
BOOST_TEST(v.at("key4") == 4);
} }
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_types) BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_types)

View File

@@ -25,6 +25,11 @@ using test_value_types = std::tuple<
namespace test namespace test
{ {
// to compare result values in BOOST_TEST().
//
// BOOST_TEST outputs the expected and actual values. Thus it includes the
// output stream operator inside. To compile it, we need operator<<s for
// containers to compare.
template<typename charT, typename traits, typename T, typename Alloc> template<typename charT, typename traits, typename T, typename Alloc>
std::basic_ostream<charT, traits>& std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const std::vector<T, Alloc>& v) operator<<(std::basic_ostream<charT, traits>& os, const std::vector<T, Alloc>& v)
@@ -121,6 +126,55 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_exact, value_type, test_value_types)
} }
#undef TOML11_TEST_GET_OR_EXACT #undef TOML11_TEST_GET_OR_EXACT
#define TOML11_TEST_GET_OR_MOVE_EXACT(toml_type, init_expr, opt_expr)\
{ \
using namespace test; \
const toml::toml_type init init_expr ; \
toml::toml_type opt opt_expr ; \
value_type v(init); \
BOOST_TEST(init != opt); \
const auto opt_ = toml::get_or(std::move(v), std::move(opt));\
BOOST_TEST(init == opt_); \
} \
/**/
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_move, value_type, test_value_types)
{
TOML11_TEST_GET_OR_MOVE_EXACT(boolean, ( true), (false))
TOML11_TEST_GET_OR_MOVE_EXACT(integer, ( 42), ( 54))
TOML11_TEST_GET_OR_MOVE_EXACT(floating, ( 3.14), ( 2.71))
TOML11_TEST_GET_OR_MOVE_EXACT(string, ("foo"), ("bar"))
TOML11_TEST_GET_OR_MOVE_EXACT(local_time, (12, 30, 45), (6, 0, 30))
TOML11_TEST_GET_OR_MOVE_EXACT(local_date, (2019, toml::month_t::Apr, 1),
(1999, toml::month_t::Jan, 2))
TOML11_TEST_GET_OR_MOVE_EXACT(local_datetime,
(toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45)),
(toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30))
)
TOML11_TEST_GET_OR_MOVE_EXACT(offset_datetime,
(toml::local_date(2019, toml::month_t::Apr, 1), toml::local_time(12, 30, 45), toml::time_offset( 9, 0)),
(toml::local_date(1999, toml::month_t::Jan, 2), toml::local_time( 6, 0, 30), toml::time_offset(-3, 0))
)
{
const typename value_type::array_type init{1,2,3,4,5};
typename value_type::array_type opt {6,7,8,9,10};
value_type v(init);
BOOST_TEST(init != opt);
const auto opt_ = toml::get_or(std::move(v), std::move(opt));
BOOST_TEST(init == opt_);
}
{
const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}};
value_type v(init);
BOOST_TEST(init != opt);
const auto opt_ = toml::get_or(std::move(v), std::move(opt));
BOOST_TEST(init == opt_);
}
}
#undef TOML11_TEST_GET_OR_MOVE_EXACT
#define TOML11_TEST_GET_OR_MODIFY(toml_type, init_expr, opt_expr)\ #define TOML11_TEST_GET_OR_MODIFY(toml_type, init_expr, opt_expr)\
{ \ { \
using namespace test; \ using namespace test; \
@@ -309,6 +363,13 @@ BOOST_AUTO_TEST_CASE(test_get_or_integer)
BOOST_TEST(42u == toml::get_or(v1, 0u)); BOOST_TEST(42u == toml::get_or(v1, 0u));
BOOST_TEST(0u == toml::get_or(v2, 0u)); BOOST_TEST(0u == toml::get_or(v2, 0u));
} }
{
toml::value v1(42);
toml::value v2(3.14);
BOOST_TEST(42u == toml::get_or(std::move(v1), 0u));
BOOST_TEST(0u == toml::get_or(std::move(v2), 0u));
}
} }
BOOST_AUTO_TEST_CASE(test_get_or_floating) BOOST_AUTO_TEST_CASE(test_get_or_floating)
@@ -319,6 +380,12 @@ BOOST_AUTO_TEST_CASE(test_get_or_floating)
BOOST_TEST(2.71f == toml::get_or(v1, 2.71f)); BOOST_TEST(2.71f == toml::get_or(v1, 2.71f));
BOOST_TEST(static_cast<float>(v2.as_floating()) == toml::get_or(v2, 2.71f)); BOOST_TEST(static_cast<float>(v2.as_floating()) == toml::get_or(v2, 2.71f));
} }
{
toml::value v1(42);
toml::value v2(3.14);
BOOST_TEST(2.71f == toml::get_or(std::move(v1), 2.71f));
BOOST_TEST(static_cast<float>(3.14) == toml::get_or(std::move(v2), 2.71f));
}
} }
BOOST_AUTO_TEST_CASE(test_get_or_string) BOOST_AUTO_TEST_CASE(test_get_or_string)
@@ -345,7 +412,16 @@ BOOST_AUTO_TEST_CASE(test_get_or_string)
BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1))); BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1)));
BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1))); BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1)));
} }
{
toml::value v1("foobar");
toml::value v2(42);
std::string s1("bazqux");
const std::string s2("bazqux");
BOOST_TEST("foobar" == toml::get_or(std::move(v1), s1));
BOOST_TEST("bazqux" == toml::get_or(std::move(v2), s1));
}
{ {
toml::value v1("foobar"); toml::value v1("foobar");
toml::value v2(42); toml::value v2(42);
@@ -357,4 +433,20 @@ BOOST_AUTO_TEST_CASE(test_get_or_string)
BOOST_TEST("foobar" == toml::get_or(v1, lit)); BOOST_TEST("foobar" == toml::get_or(v1, lit));
BOOST_TEST("bazqux" == toml::get_or(v2, lit)); BOOST_TEST("bazqux" == toml::get_or(v2, lit));
} }
{
toml::value v1("foobar");
toml::value v2(42);
BOOST_TEST("foobar" == toml::get_or(std::move(v1), "bazqux"));
BOOST_TEST("bazqux" == toml::get_or(std::move(v2), "bazqux"));
}
{
toml::value v1("foobar");
toml::value v2(42);
const char* lit = "bazqux";
BOOST_TEST("foobar" == toml::get_or(v1, lit));
BOOST_TEST("bazqux" == toml::get_or(v2, lit));
}
} }

View File

@@ -35,27 +35,35 @@ BOOST_AUTO_TEST_CASE(test_fractional_invalid)
BOOST_AUTO_TEST_CASE(test_exponential_valid) BOOST_AUTO_TEST_CASE(test_exponential_valid)
{ {
TOML11_TEST_LEX_ACCEPT(lex_float, "1e10", "1e10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1e10", "1e10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1e+10", "1e+10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1e+10", "1e+10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1e-10", "1e-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1e-10", "1e-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "+1e10", "+1e10"); TOML11_TEST_LEX_ACCEPT(lex_float, "+1e10", "+1e10");
TOML11_TEST_LEX_ACCEPT(lex_float, "+1e+10", "+1e+10"); TOML11_TEST_LEX_ACCEPT(lex_float, "+1e+10", "+1e+10");
TOML11_TEST_LEX_ACCEPT(lex_float, "+1e-10", "+1e-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "+1e-10", "+1e-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "-1e10", "-1e10"); TOML11_TEST_LEX_ACCEPT(lex_float, "-1e10", "-1e10");
TOML11_TEST_LEX_ACCEPT(lex_float, "-1e+10", "-1e+10"); TOML11_TEST_LEX_ACCEPT(lex_float, "-1e+10", "-1e+10");
TOML11_TEST_LEX_ACCEPT(lex_float, "-1e-10", "-1e-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "-1e-10", "-1e-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "123e-10", "123e-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "123e-10", "123e-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1E10", "1E10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1E10", "1E10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1E+10", "1E+10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1E+10", "1E+10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1E-10", "1E-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1E-10", "1E-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "123E-10", "123E-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "123E-10", "123E-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-10", "1_2_3E-10"); TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-10", "1_2_3E-10");
TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-1_0", "1_2_3E-1_0"); TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-1_0", "1_2_3E-1_0");
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-01", "1_2_3E-01");
TOML11_TEST_LEX_ACCEPT(lex_float, "1_2_3E-0_1", "1_2_3E-0_1");
#endif
} }
BOOST_AUTO_TEST_CASE(test_exponential_invalid) BOOST_AUTO_TEST_CASE(test_exponential_invalid)
{ {
TOML11_TEST_LEX_ACCEPT(lex_float, "1e1E0", "1e1"); // accept partially
TOML11_TEST_LEX_ACCEPT(lex_float, "1e1E0", "1e1");
TOML11_TEST_LEX_ACCEPT(lex_float, "1E1e0", "1E1"); TOML11_TEST_LEX_ACCEPT(lex_float, "1E1e0", "1E1");
} }
@@ -64,12 +72,26 @@ BOOST_AUTO_TEST_CASE(test_both_valid)
TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e23", "6.02e23"); TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e23", "6.02e23");
TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e+23", "6.02e+23"); TOML11_TEST_LEX_ACCEPT(lex_float, "6.02e+23", "6.02e+23");
TOML11_TEST_LEX_ACCEPT(lex_float, "1.112_650_06e-17", "1.112_650_06e-17"); TOML11_TEST_LEX_ACCEPT(lex_float, "1.112_650_06e-17", "1.112_650_06e-17");
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e-07", "1.0e-07");
#endif
} }
BOOST_AUTO_TEST_CASE(test_both_invalid) BOOST_AUTO_TEST_CASE(test_both_invalid)
{ {
TOML11_TEST_LEX_ACCEPT(lex_float, "1e1.0", "1e1");
TOML11_TEST_LEX_REJECT(lex_float, "01e1.0"); TOML11_TEST_LEX_REJECT(lex_float, "01e1.0");
// accept partially
TOML11_TEST_LEX_ACCEPT(lex_float, "1e1.0", "1e1");
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e_01", "1.0");
TOML11_TEST_LEX_ACCEPT(lex_float, "1.0e0__1", "1.0e0");
#endif
} }
BOOST_AUTO_TEST_CASE(test_special_floating_point) BOOST_AUTO_TEST_CASE(test_special_floating_point)

View File

@@ -68,6 +68,13 @@ BOOST_AUTO_TEST_CASE(test_exponential)
TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-1_0", 123e-10); TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-1_0", 123e-10);
TOML11_TEST_PARSE_EQUAL(parse_floating, "+0e0", 0.0); TOML11_TEST_PARSE_EQUAL(parse_floating, "+0e0", 0.0);
TOML11_TEST_PARSE_EQUAL(parse_floating, "-0e0", -0.0); TOML11_TEST_PARSE_EQUAL(parse_floating, "-0e0", -0.0);
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-01", 123e-1);
TOML11_TEST_PARSE_EQUAL(parse_floating, "1_2_3E-0_1", 123e-1);
#endif
} }
BOOST_AUTO_TEST_CASE(test_exponential_value) BOOST_AUTO_TEST_CASE(test_exponential_value)
@@ -90,6 +97,13 @@ BOOST_AUTO_TEST_CASE(test_exponential_value)
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3E-1_0", value(123e-10)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3E-1_0", value(123e-10));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+0e0", value( 0.0)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+0e0", value( 0.0));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-0e0", value(-0.0)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-0e0", value(-0.0));
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3E-01", value(123e-1));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3E-0_1", value(123e-1));
#endif
} }
BOOST_AUTO_TEST_CASE(test_fe) BOOST_AUTO_TEST_CASE(test_fe)
{ {
@@ -102,6 +116,12 @@ BOOST_AUTO_TEST_CASE(test_fe_vaule)
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "6.02e23", value(6.02e23)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "6.02e23", value(6.02e23));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "6.02e+23", value(6.02e23)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "6.02e+23", value(6.02e23));
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1.112_650_06e-17", value(1.11265006e-17)); TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1.112_650_06e-17", value(1.11265006e-17));
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
BOOST_TEST_MESSAGE("testing an unreleased toml feature: leading zeroes in float exponent part");
// toml-lang/toml master permits leading 0s in exp part (unreleased)
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "3.141_5e-01", value(3.1415e-1));
#endif
} }
BOOST_AUTO_TEST_CASE(test_inf) BOOST_AUTO_TEST_CASE(test_inf)

View File

@@ -905,3 +905,32 @@ BOOST_AUTO_TEST_CASE(test_value_empty)
BOOST_CHECK_THROW(v1.as_array(), toml::type_error); BOOST_CHECK_THROW(v1.as_array(), toml::type_error);
BOOST_CHECK_THROW(v1.as_table(), toml::type_error); BOOST_CHECK_THROW(v1.as_table(), toml::type_error);
} }
BOOST_AUTO_TEST_CASE(test_value_at)
{
{
toml::value v1{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}};
BOOST_TEST(v1.at("foo").as_integer() == 42);
BOOST_TEST(v1.at("bar").as_floating() == 3.14);
BOOST_TEST(v1.at("baz").as_string() == "qux");
BOOST_CHECK_THROW(v1.at(0), toml::type_error);
BOOST_CHECK_THROW(v1.at("quux"), std::out_of_range);
}
{
toml::value v1{1,2,3,4,5};
BOOST_TEST(v1.at(0).as_integer() == 1);
BOOST_TEST(v1.at(1).as_integer() == 2);
BOOST_TEST(v1.at(2).as_integer() == 3);
BOOST_TEST(v1.at(3).as_integer() == 4);
BOOST_TEST(v1.at(4).as_integer() == 5);
BOOST_CHECK_THROW(v1.at("foo"), toml::type_error);
BOOST_CHECK_THROW(v1.at(5), std::out_of_range);
}
}

View File

@@ -31,10 +31,10 @@ get(const basic_value<C, M, V>& v)
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::is_exact_toml_type<T, basic_value<C, M, V>>::value, T> && detail::enable_if_t<detail::is_exact_toml_type<T, basic_value<C, M, V>>::value, T>
get(basic_value<C, M, V>&& v) get(basic_value<C, M, V>&& v)
{ {
return std::move(v).template cast<detail::type_to_enum<T, basic_value<C, M, V>>::value>(); return T(std::move(v).template cast<detail::type_to_enum<T, basic_value<C, M, V>>::value>());
} }
// ============================================================================ // ============================================================================
@@ -58,10 +58,10 @@ get(const basic_value<C, M, V>& v)
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
inline detail::enable_if_t<std::is_same<T, basic_value<C, M, V>>::value, T> && inline detail::enable_if_t<std::is_same<T, basic_value<C, M, V>>::value, T>
get(basic_value<C, M, V>&& v) get(basic_value<C, M, V>&& v)
{ {
return std::move(v); return basic_value<C, M, V>(std::move(v));
} }
// ============================================================================ // ============================================================================
@@ -90,7 +90,7 @@ inline detail::enable_if_t<detail::conjunction<
>::value, T> >::value, T>
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
return static_cast<T>(v.template cast<value_t::integer>()); return static_cast<T>(v.as_integer());
} }
// ============================================================================ // ============================================================================
@@ -105,7 +105,7 @@ inline detail::enable_if_t<detail::conjunction<
>::value, T> >::value, T>
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
return static_cast<T>(v.template cast<value_t::floating>()); return static_cast<T>(v.as_floating());
} }
// ============================================================================ // ============================================================================
@@ -117,7 +117,7 @@ template<typename T, typename C,
inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string>& inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string>&
get(basic_value<C, M, V>& v) get(basic_value<C, M, V>& v)
{ {
return v.template cast<value_t::string>().str; return v.as_string().str;
} }
template<typename T, typename C, template<typename T, typename C,
@@ -125,15 +125,15 @@ template<typename T, typename C,
inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string> const& inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string> const&
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
return v.template cast<value_t::string>().str; return v.as_string().str;
} }
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string> const& inline detail::enable_if_t<std::is_same<T, std::string>::value, std::string>
get(basic_value<C, M, V>&& v) get(basic_value<C, M, V>&& v)
{ {
return std::move(v.template cast<value_t::string>().str); return std::string(std::move(v.as_string().str));
} }
// ============================================================================ // ============================================================================
@@ -145,7 +145,7 @@ template<typename T, typename C,
inline detail::enable_if_t<std::is_same<T, std::string_view>::value, std::string_view> inline detail::enable_if_t<std::is_same<T, std::string_view>::value, std::string_view>
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
return std::string_view(v.template cast<value_t::string>().str); return std::string_view(v.as_string().str);
} }
#endif #endif
@@ -158,7 +158,7 @@ inline detail::enable_if_t<detail::is_chrono_duration<T>::value, T>
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
return std::chrono::duration_cast<T>( return std::chrono::duration_cast<T>(
std::chrono::nanoseconds(v.template cast<value_t::local_time>())); std::chrono::nanoseconds(v.as_local_time()));
} }
// ============================================================================ // ============================================================================
@@ -174,18 +174,15 @@ get(const basic_value<C, M, V>& v)
{ {
case value_t::local_date: case value_t::local_date:
{ {
return std::chrono::system_clock::time_point( return std::chrono::system_clock::time_point(v.as_local_date());
v.template cast<value_t::local_date>());
} }
case value_t::local_datetime: case value_t::local_datetime:
{ {
return std::chrono::system_clock::time_point( return std::chrono::system_clock::time_point(v.as_local_datetime());
v.template cast<value_t::local_datetime>());
} }
case value_t::offset_datetime: case value_t::offset_datetime:
{ {
return std::chrono::system_clock::time_point( return std::chrono::system_clock::time_point(v.as_offset_datetime());
v.template cast<value_t::offset_datetime>());
} }
default: default:
{ {
@@ -259,7 +256,7 @@ get(const basic_value<C, M, V>&);
// toml::from<T>::from_toml(v) // toml::from<T>::from_toml(v)
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V, template<typename ...> class M, template<typename ...> class V,
std::size_t S = sizeof(::toml::into<T>)> std::size_t S = sizeof(::toml::from<T>)>
T get(const basic_value<C, M, V>&); T get(const basic_value<C, M, V>&);
// ============================================================================ // ============================================================================
@@ -276,7 +273,7 @@ detail::enable_if_t<detail::conjunction<
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
using value_type = typename T::value_type; using value_type = typename T::value_type;
const auto& ar = v.template cast<value_t::array>(); const auto& ar = v.as_array();
T container; T container;
container.resize(ar.size()); container.resize(ar.size());
std::transform(ar.cbegin(), ar.cend(), container.begin(), std::transform(ar.cbegin(), ar.cend(), container.begin(),
@@ -298,7 +295,7 @@ detail::enable_if_t<detail::conjunction<
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
using value_type = typename T::value_type; using value_type = typename T::value_type;
const auto& ar = v.template cast<value_t::array>(); const auto& ar = v.as_array();
T container; T container;
if(ar.size() != container.size()) if(ar.size() != container.size())
@@ -325,7 +322,7 @@ get(const basic_value<C, M, V>& v)
using first_type = typename T::first_type; using first_type = typename T::first_type;
using second_type = typename T::second_type; using second_type = typename T::second_type;
const auto& ar = v.template cast<value_t::array>(); const auto& ar = v.as_array();
if(ar.size() != 2) if(ar.size() != 2)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -356,7 +353,7 @@ template<typename T, typename C,
detail::enable_if_t<detail::is_std_tuple<T>::value, T> detail::enable_if_t<detail::is_std_tuple<T>::value, T>
get(const basic_value<C, M, V>& v) get(const basic_value<C, M, V>& v)
{ {
const auto& ar = v.template cast<value_t::array>(); const auto& ar = v.as_array();
if(ar.size() != std::tuple_size<T>::value) if(ar.size() != std::tuple_size<T>::value)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -388,7 +385,7 @@ get(const basic_value<C, M, V>& v)
"toml::get only supports map type of which key_type is " "toml::get only supports map type of which key_type is "
"convertible from std::string."); "convertible from std::string.");
T map; T map;
for(const auto& kv : v.template cast<value_t::table>()) for(const auto& kv : v.as_table())
{ {
map[key_type(kv.first)] = ::toml::get<mapped_type>(kv.second); map[key_type(kv.first)] = ::toml::get<mapped_type>(kv.second);
} }
@@ -421,7 +418,7 @@ T get(const basic_value<C, M, V>& v)
} }
// ============================================================================ // ============================================================================
// find and get // find
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// these overloads do not require to set T. and returns value itself. // these overloads do not require to set T. and returns value itself.
@@ -429,7 +426,7 @@ template<typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
basic_value<C, M, V> const& find(const basic_value<C, M, V>& v, const key& ky) basic_value<C, M, V> const& find(const basic_value<C, M, V>& v, const key& ky)
{ {
const auto& tab = v.template cast<value_t::table>(); const auto& tab = v.as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -443,7 +440,7 @@ template<typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
basic_value<C, M, V>& find(basic_value<C, M, V>& v, const key& ky) basic_value<C, M, V>& find(basic_value<C, M, V>& v, const key& ky)
{ {
auto& tab = v.template cast<value_t::table>(); auto& tab = v.as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -455,9 +452,9 @@ basic_value<C, M, V>& find(basic_value<C, M, V>& v, const key& ky)
} }
template<typename C, template<typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
basic_value<C, M, V>&& find(basic_value<C, M, V>&& v, const key& ky) basic_value<C, M, V> find(basic_value<C, M, V>&& v, const key& ky)
{ {
auto& tab = v.template cast<value_t::table>(); typename basic_value<C, M, V>::table_type tab = std::move(v).as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -465,7 +462,7 @@ basic_value<C, M, V>&& find(basic_value<C, M, V>&& v, const key& ky)
{std::addressof(detail::get_region(v)), "in this table"} {std::addressof(detail::get_region(v)), "in this table"}
})); }));
} }
return std::move(tab.at(ky)); return basic_value<C, M, V>(std::move(tab.at(ky)));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -476,7 +473,7 @@ template<typename T, typename C,
decltype(::toml::get<T>(std::declval<basic_value<C, M, V> const&>())) decltype(::toml::get<T>(std::declval<basic_value<C, M, V> const&>()))
find(const basic_value<C, M, V>& v, const key& ky) find(const basic_value<C, M, V>& v, const key& ky)
{ {
const auto& tab = v.template cast<value_t::table>(); const auto& tab = v.as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -492,7 +489,7 @@ template<typename T, typename C,
decltype(::toml::get<T>(std::declval<basic_value<C, M, V>&>())) decltype(::toml::get<T>(std::declval<basic_value<C, M, V>&>()))
find(basic_value<C, M, V>& v, const key& ky) find(basic_value<C, M, V>& v, const key& ky)
{ {
auto& tab = v.template cast<value_t::table>(); auto& tab = v.as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -508,7 +505,7 @@ template<typename T, typename C,
decltype(::toml::get<T>(std::declval<basic_value<C, M, V>&&>())) decltype(::toml::get<T>(std::declval<basic_value<C, M, V>&&>()))
find(basic_value<C, M, V>&& v, const key& ky) find(basic_value<C, M, V>&& v, const key& ky)
{ {
auto& tab = v.template cast<value_t::table>(); typename basic_value<C, M, V>::table_type tab = std::move(v).as_table();
if(tab.count(ky) == 0) if(tab.count(ky) == 0)
{ {
throw std::out_of_range(detail::format_underline(concat_to_string( throw std::out_of_range(detail::format_underline(concat_to_string(
@@ -541,7 +538,7 @@ find(basic_value<C, M, V>& v, const ::toml::key& ky, Ts&& ... keys)
template<typename C, template<typename C,
template<typename ...> class M, template<typename ...> class V, template<typename ...> class M, template<typename ...> class V,
typename ... Ts> typename ... Ts>
basic_value<C, M, V>&& basic_value<C, M, V>
find(basic_value<C, M, V>&& v, const ::toml::key& ky, Ts&& ... keys) find(basic_value<C, M, V>&& v, const ::toml::key& ky, Ts&& ... keys)
{ {
return ::toml::find(::toml::find(std::move(v), ky), std::forward<Ts>(keys)...); return ::toml::find(::toml::find(std::move(v), ky), std::forward<Ts>(keys)...);
@@ -608,8 +605,7 @@ get_or(const basic_value<C, M, V>& v, const T& opt)
{ {
try try
{ {
return get<typename std::remove_cv< return get<detail::remove_cvref_t<T>>(v);
typename std::remove_reference<T>::type>::type>(v);
} }
catch(...) catch(...)
{ {
@@ -624,8 +620,7 @@ get_or(basic_value<C, M, V>& v, T& opt)
{ {
try try
{ {
return get<typename std::remove_cv< return get<detail::remove_cvref_t<T>>(v);
typename std::remove_reference<T>::type>::type>(v);
} }
catch(...) catch(...)
{ {
@@ -634,18 +629,17 @@ get_or(basic_value<C, M, V>& v, T& opt)
} }
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t< detail::enable_if_t<detail::is_exact_toml_type<detail::remove_cvref_t<T>,
detail::is_exact_toml_type<T, basic_value<C, M, V>>::value, T>&& basic_value<C, M, V>>::value, detail::remove_cvref_t<T>>
get_or(basic_value<C, M, V>&& v, T&& opt) get_or(basic_value<C, M, V>&& v, T&& opt)
{ {
try try
{ {
return get<typename std::remove_cv< return get<detail::remove_cvref_t<T>>(std::move(v));
typename std::remove_reference<T>::type>::type>(v);
} }
catch(...) catch(...)
{ {
return opt; return detail::remove_cvref_t<T>(std::forward<T>(opt));
} }
} }
@@ -654,14 +648,13 @@ get_or(basic_value<C, M, V>&& v, T&& opt)
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<std::is_same< detail::enable_if_t<std::is_same<detail::remove_cvref_t<T>, std::string>::value,
typename std::remove_cv<typename std::remove_reference<T>::type>::type, std::string> const&
std::string>::value, std::string> const& get_or(const basic_value<C, M, V>& v, const T& opt)
get_or(const basic_value<C, M, V>& v, T&& opt)
{ {
try try
{ {
return v.template cast<value_t::string>().str; return v.as_string().str;
} }
catch(...) catch(...)
{ {
@@ -675,7 +668,7 @@ get_or(basic_value<C, M, V>& v, T& opt)
{ {
try try
{ {
return v.template cast<value_t::string>().str; return v.as_string().str;
} }
catch(...) catch(...)
{ {
@@ -684,18 +677,17 @@ get_or(basic_value<C, M, V>& v, T& opt)
} }
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<std::is_same< detail::enable_if_t<
typename std::remove_cv<typename std::remove_reference<T>::type>::type, std::is_same<detail::remove_cvref_t<T>, std::string>::value, std::string>
std::string>::value, std::string>
get_or(basic_value<C, M, V>&& v, T&& opt) get_or(basic_value<C, M, V>&& v, T&& opt)
{ {
try try
{ {
return std::move(v.template cast<value_t::string>().str); return std::move(v.as_string().str);
} }
catch(...) catch(...)
{ {
return std::forward<T>(opt); return std::string(std::forward<T>(opt));
} }
} }
@@ -710,11 +702,11 @@ get_or(const basic_value<C, M, V>& v, T&& opt)
{ {
try try
{ {
return std::move(v.template cast<value_t::string>().str); return std::move(v.as_string().str);
} }
catch(...) catch(...)
{ {
return std::string(opt); return std::string(std::forward<T>(opt));
} }
} }
@@ -724,24 +716,21 @@ get_or(const basic_value<C, M, V>& v, T&& opt)
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t<detail::conjunction< detail::enable_if_t<detail::conjunction<
detail::negation<detail::is_exact_toml_type< detail::negation<detail::is_exact_toml_type<detail::remove_cvref_t<T>,
typename std::remove_cv<typename std::remove_reference<T>::type>::type,
basic_value<C, M, V>>>, basic_value<C, M, V>>>,
detail::negation<std::is_same<std::string, detail::negation<std::is_same<std::string, detail::remove_cvref_t<T>>>,
typename std::remove_cv<typename std::remove_reference<T>::type>::type>>,
detail::negation<detail::is_string_literal< detail::negation<detail::is_string_literal<
typename std::remove_reference<T>::type>> typename std::remove_reference<T>::type>>
>::value, typename std::remove_reference<T>::type> >::value, detail::remove_cvref_t<T>>
get_or(const basic_value<C, M, V>& v, T&& opt) get_or(const basic_value<C, M, V>& v, T&& opt)
{ {
try try
{ {
return get<typename std::remove_cv< return get<detail::remove_cvref_t<T>>(v);
typename std::remove_reference<T>::type>::type>(v);
} }
catch(...) catch(...)
{ {
return std::forward<T>(opt); return detail::remove_cvref_t<T>(std::forward<T>(opt));
} }
} }
@@ -768,7 +757,7 @@ find_or(basic_value<C, M, V>& v, const toml::key& ky, basic_value<C, M, V>& opt)
if(!v.is_table()) {return opt;} if(!v.is_table()) {return opt;}
auto& tab = v.as_table(); auto& tab = v.as_table();
if(tab.count(ky) == 0) {return opt;} if(tab.count(ky) == 0) {return opt;}
return tab[ky]; return tab.at(ky);
} }
template<typename C, template<typename C,
@@ -779,7 +768,7 @@ find_or(basic_value<C, M, V>&& v, const toml::key& ky, basic_value<C, M, V>&& op
if(!v.is_table()) {return opt;} if(!v.is_table()) {return opt;}
auto tab = std::move(v).as_table(); auto tab = std::move(v).as_table();
if(tab.count(ky) == 0) {return opt;} if(tab.count(ky) == 0) {return opt;}
return std::move(tab[ky]); return basic_value<C, M, V>(std::move(tab.at(ky)));
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -805,19 +794,20 @@ find_or(basic_value<C, M, V>& v, const toml::key& ky, T& opt)
if(!v.is_table()) {return opt;} if(!v.is_table()) {return opt;}
auto& tab = v.as_table(); auto& tab = v.as_table();
if(tab.count(ky) == 0) {return opt;} if(tab.count(ky) == 0) {return opt;}
return get_or(tab[ky], opt); return get_or(tab.at(ky), opt);
} }
template<typename T, typename C, template<typename T, typename C,
template<typename ...> class M, template<typename ...> class V> template<typename ...> class M, template<typename ...> class V>
detail::enable_if_t< detail::enable_if_t<
detail::is_exact_toml_type<T, basic_value<C, M, V>>::value, T>&& detail::is_exact_toml_type<T, basic_value<C, M, V>>::value,
detail::remove_cvref_t<T>>
find_or(basic_value<C, M, V>&& v, const toml::key& ky, T&& opt) find_or(basic_value<C, M, V>&& v, const toml::key& ky, T&& opt)
{ {
if(!v.is_table()) {return opt;} if(!v.is_table()) {return std::forward<T>(opt);}
auto tab = std::move(v).as_table(); auto tab = std::move(v).as_table();
if(tab.count(ky) == 0) {return opt;} if(tab.count(ky) == 0) {return std::forward<T>(opt);}
return get_or(std::move(tab[ky]), std::forward<T>(opt)); return get_or(std::move(tab.at(ky)), std::forward<T>(opt));
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@@ -876,15 +866,13 @@ template<typename T, typename C,
detail::enable_if_t<detail::conjunction< detail::enable_if_t<detail::conjunction<
// T is not an exact toml type // T is not an exact toml type
detail::negation<detail::is_exact_toml_type< detail::negation<detail::is_exact_toml_type<
typename std::remove_cv<typename std::remove_reference<T>::type>::type, detail::remove_cvref_t<T>, basic_value<C, M, V>>>,
basic_value<C, M, V>>>,
// T is not std::string // T is not std::string
detail::negation<std::is_same<std::string, detail::negation<std::is_same<std::string, detail::remove_cvref_t<T>>>,
typename std::remove_cv<typename std::remove_reference<T>::type>::type>>,
// T is not a string literal // T is not a string literal
detail::negation<detail::is_string_literal< detail::negation<detail::is_string_literal<
typename std::remove_reference<T>::type>> typename std::remove_reference<T>::type>>
>::value, typename std::remove_cv<typename std::remove_reference<T>::type>::type> >::value, detail::remove_cvref_t<T>>
find_or(const basic_value<C, M, V>& v, const toml::key& ky, T&& opt) find_or(const basic_value<C, M, V>& v, const toml::key& ky, T&& opt)
{ {
if(!v.is_table()) {return std::forward<T>(opt);} if(!v.is_table()) {return std::forward<T>(opt);}
@@ -923,21 +911,6 @@ expect(const basic_value<C, M, V>& v, const toml::key& k) noexcept
return err(e.what()); return err(e.what());
} }
} }
template<typename T, typename Table>
detail::enable_if_t<detail::conjunction<
detail::is_map<Table>, detail::is_basic_value<typename Table::mapped_type>
>::value, result<T, std::string>>
expect(const Table& t, const toml::key& k,
std::string tablename = "unknown table") noexcept
{
try
{
return ok(find<T>(t, k, std::move(tablename)));
}
catch(const std::exception& e)
{
return err(e.what());
}
}
} // toml } // toml
#endif// TOML11_GET #endif// TOML11_GET

View File

@@ -63,12 +63,22 @@ using lex_integer = either<lex_bin_int, lex_oct_int, lex_hex_int, lex_dec_int>;
using lex_inf = sequence<character<'i'>, character<'n'>, character<'f'>>; using lex_inf = sequence<character<'i'>, character<'n'>, character<'f'>>;
using lex_nan = sequence<character<'n'>, character<'a'>, character<'n'>>; using lex_nan = sequence<character<'n'>, character<'a'>, character<'n'>>;
using lex_special_float = sequence<maybe<lex_sign>, either<lex_inf, lex_nan>>; using lex_special_float = sequence<maybe<lex_sign>, either<lex_inf, lex_nan>>;
using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>, lex_dec_int>;
using lex_zero_prefixable_int = sequence<lex_digit, repeat<either<lex_digit, using lex_zero_prefixable_int = sequence<lex_digit, repeat<either<lex_digit,
sequence<lex_underscore, lex_digit>>, unlimited>>; sequence<lex_underscore, lex_digit>>, unlimited>>;
using lex_fractional_part = sequence<character<'.'>, lex_zero_prefixable_int>; using lex_fractional_part = sequence<character<'.'>, lex_zero_prefixable_int>;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
// use toml-lang/toml HEAD
using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>,
maybe<lex_sign>, lex_zero_prefixable_int>;
#else
// strictly TOML v0.5.0
using lex_exponent_part = sequence<either<character<'e'>, character<'E'>>,
lex_dec_int>;
#endif
using lex_float = either<lex_special_float, using lex_float = either<lex_special_float,
sequence<lex_dec_int, either<lex_exponent_part, sequence<lex_dec_int, either<lex_exponent_part,
sequence<lex_fractional_part, maybe<lex_exponent_part>>>>>; sequence<lex_fractional_part, maybe<lex_exponent_part>>>>>;
@@ -115,10 +125,17 @@ using lex_local_time = lex_partial_time;
// =========================================================================== // ===========================================================================
using lex_quotation_mark = character<'"'>; using lex_quotation_mark = character<'"'>;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
using lex_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 (tab) using lex_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 (tab)
in_range<0x0a, 0x1F>, // is allowed in_range<0x0a, 0x1F>, // is allowed
character<0x22>, character<0x5C>, character<0x22>, character<0x5C>,
character<0x7F>>>; character<0x7F>>>;
#else
using lex_basic_unescaped = exclude<either<in_range<0x00, 0x1F>,
character<0x22>, character<0x5C>,
character<0x7F>>>;
#endif
using lex_escape = character<'\\'>; using lex_escape = character<'\\'>;
using lex_escape_unicode_short = sequence<character<'u'>, using lex_escape_unicode_short = sequence<character<'u'>,
repeat<lex_hex_dig, exactly<4>>>; repeat<lex_hex_dig, exactly<4>>>;
@@ -138,11 +155,18 @@ using lex_basic_string = sequence<lex_quotation_mark,
lex_quotation_mark>; lex_quotation_mark>;
using lex_ml_basic_string_delim = repeat<lex_quotation_mark, exactly<3>>; using lex_ml_basic_string_delim = repeat<lex_quotation_mark, exactly<3>>;
#ifdef TOML11_USE_UNRELEASED_TOML_FEATURES
using lex_ml_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09 using lex_ml_basic_unescaped = exclude<either<in_range<0x00, 0x08>, // 0x09
in_range<0x0a, 0x1F>, // is tab in_range<0x0a, 0x1F>, // is tab
character<0x5C>, character<0x5C>,
character<0x7F>, character<0x7F>,
lex_ml_basic_string_delim>>; lex_ml_basic_string_delim>>;
#else // TOML v0.5.0
using lex_ml_basic_unescaped = exclude<either<in_range<0x00,0x1F>,
character<0x5C>,
character<0x7F>,
lex_ml_basic_string_delim>>;
#endif
using lex_ml_basic_escaped_newline = sequence< using lex_ml_basic_escaped_newline = sequence<
lex_escape, maybe<lex_ws>, lex_newline, lex_escape, maybe<lex_ws>, lex_newline,

View File

@@ -240,6 +240,19 @@ disjunction<
> >
>{}; >{};
// ---------------------------------------------------------------------------
// C++20 remove_cvref_t
template<typename T>
struct remove_cvref
{
using type = typename std::remove_cv<
typename std::remove_reference<T>::type>::type;
};
template<typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
}// detail }// detail
}//toml }//toml
#endif // TOML_TRAITS #endif // TOML_TRAITS

View File

@@ -1567,6 +1567,28 @@ class basic_value
return std::move(this->table_.value()); return std::move(this->table_.value());
} }
// accessors =============================================================
//
// may throw type_error or out_of_range
//
value_type& at(const key& k)
{
return this->as_table().at(k);
}
value_type const& at(const key& k) const
{
return this->as_table().at(k);
}
value_type& at(const std::size_t idx)
{
return this->as_array().at(idx);
}
value_type const& at(const std::size_t idx) const
{
return this->as_array().at(idx);
}
source_location location() const source_location location() const
{ {
return source_location(this->region_info_.get()); return source_location(this->region_info_.get());