mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Compare commits
435 Commits
v2.0.0
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a251f582e | ||
|
|
74ef494797 | ||
|
|
3a5f8a4b88 | ||
|
|
4d2b24b647 | ||
|
|
3fcb6bb20d | ||
|
|
1e8af710a0 | ||
|
|
0ca8eeeb09 | ||
|
|
a343ffd2a1 | ||
|
|
b79797d2c7 | ||
|
|
90918b6d76 | ||
|
|
dd9b04ae3b | ||
|
|
4032b438c0 | ||
|
|
7b37d876ae | ||
|
|
713b42e589 | ||
|
|
1694f74510 | ||
|
|
9f69ffa993 | ||
|
|
0cee58b0b1 | ||
|
|
ab1ef63da6 | ||
|
|
e8d535e485 | ||
|
|
d4afed5bbb | ||
|
|
3ef8bddb6d | ||
|
|
a68543a895 | ||
|
|
ec839bbd75 | ||
|
|
ecf55f86d6 | ||
|
|
3b71f80652 | ||
|
|
be2d2aec52 | ||
|
|
be04bf1302 | ||
|
|
427706d671 | ||
|
|
71ff54e76c | ||
|
|
8208bbf236 | ||
|
|
f689d26294 | ||
|
|
9e6d8e76d0 | ||
|
|
0e2e4a26be | ||
|
|
092db50700 | ||
|
|
295e9bb795 | ||
|
|
dd2238e1ad | ||
|
|
5dfa88a1b3 | ||
|
|
37b4442d7f | ||
|
|
48aa0a4c67 | ||
|
|
86a1f7ad75 | ||
|
|
99c10dd6bc | ||
|
|
7d087ef2a8 | ||
|
|
a0d74a5542 | ||
|
|
c3922c0d51 | ||
|
|
5e5a757208 | ||
|
|
f178379c07 | ||
|
|
321db42b1c | ||
|
|
1bf9e42835 | ||
|
|
3379ed82ec | ||
|
|
9663a6bbdb | ||
|
|
4a2c823d56 | ||
|
|
9a47c2a15a | ||
|
|
3311d00845 | ||
|
|
24c28c7f4f | ||
|
|
cab3144507 | ||
|
|
7e5859ba73 | ||
|
|
dee32e7d5e | ||
|
|
53a185e7a9 | ||
|
|
fd980a8c5d | ||
|
|
73ac43d70c | ||
|
|
adcd75e017 | ||
|
|
3613580bb3 | ||
|
|
d9f9df61a2 | ||
|
|
32d5c9e924 | ||
|
|
262f9c5fcc | ||
|
|
86e55c3bf7 | ||
|
|
159283fdad | ||
|
|
fb5834caab | ||
|
|
ca084abe90 | ||
|
|
7b1a788e2d | ||
|
|
228487eafd | ||
|
|
f744a792e2 | ||
|
|
bf2dc76d5e | ||
|
|
4d267cadf4 | ||
|
|
bc68a9d9ee | ||
|
|
4008c24e84 | ||
|
|
c2b0de623f | ||
|
|
af11d56e79 | ||
|
|
5cb7c961aa | ||
|
|
bf4eae0b76 | ||
|
|
6399d44e3b | ||
|
|
d10c0725fd | ||
|
|
7eac3a3028 | ||
|
|
57b5545ba2 | ||
|
|
f36b39c04f | ||
|
|
569341a514 | ||
|
|
0357d8fb57 | ||
|
|
00d40140ac | ||
|
|
1bfe8f1f54 | ||
|
|
b3300fad2a | ||
|
|
94bcf0aae9 | ||
|
|
bc143263cd | ||
|
|
0ef232a1e0 | ||
|
|
0604cf813a | ||
|
|
10f410a02c | ||
|
|
12ef0f6287 | ||
|
|
d9ad0e4b92 | ||
|
|
1b19d5f1eb | ||
|
|
fd7da05798 | ||
|
|
cbaaaaca7c | ||
|
|
cf1c9371b6 | ||
|
|
62e8d58d8d | ||
|
|
fec4e1db9a | ||
|
|
8665272bab | ||
|
|
cc4a9c8d5d | ||
|
|
af19dfe032 | ||
|
|
64dc086878 | ||
|
|
9acc55a7ac | ||
|
|
177022b2cb | ||
|
|
5726d10339 | ||
|
|
a6706f7879 | ||
|
|
558349170d | ||
|
|
eb4eca86db | ||
|
|
d8a9ee4f72 | ||
|
|
acbc2a73cb | ||
|
|
b2daf916b3 | ||
|
|
e66bb3d359 | ||
|
|
cfaa94f072 | ||
|
|
2f4f3efbf0 | ||
|
|
06ae67502a | ||
|
|
6345910c3e | ||
|
|
9948549b62 | ||
|
|
54d46f08c3 | ||
|
|
57cb806e14 | ||
|
|
d6f3654185 | ||
|
|
8befe3f1ad | ||
|
|
2d43119ac7 | ||
|
|
436af12815 | ||
|
|
4f4d4380f2 | ||
|
|
31debcb8aa | ||
|
|
2afa0ff0c3 | ||
|
|
46047c48bf | ||
|
|
897aecf5d4 | ||
|
|
7db8388d17 | ||
|
|
62c993e096 | ||
|
|
014d882f8f | ||
|
|
e781545c53 | ||
|
|
a8b5fef827 | ||
|
|
7258c52334 | ||
|
|
407d9223f6 | ||
|
|
53efaed179 | ||
|
|
d7c5606dcf | ||
|
|
761718b3b9 | ||
|
|
ae2bafa907 | ||
|
|
f19b3822bb | ||
|
|
2cbb93d86e | ||
|
|
a19b94511b | ||
|
|
cf1114b47b | ||
|
|
ad3c1950f2 | ||
|
|
296ba060ef | ||
|
|
fe8a909213 | ||
|
|
c313e1382c | ||
|
|
5fe166e375 | ||
|
|
319365f86b | ||
|
|
89f0ace6ee | ||
|
|
2e34035e7a | ||
|
|
7d34436535 | ||
|
|
8456186eac | ||
|
|
e094d6e85a | ||
|
|
4664f91517 | ||
|
|
c0b6ca762a | ||
|
|
5ef9890d0c | ||
|
|
bda337b51f | ||
|
|
6569c26e1b | ||
|
|
6d17d5f60f | ||
|
|
c00eeb18ef | ||
|
|
3ce1aa31f3 | ||
|
|
cf28c3fb95 | ||
|
|
6de494598a | ||
|
|
b06ae03deb | ||
|
|
725d915ba9 | ||
|
|
e1556183d1 | ||
|
|
9676499ab5 | ||
|
|
5792411d5e | ||
|
|
44184026f9 | ||
|
|
898423166f | ||
|
|
f9b5166c09 | ||
|
|
5c5d8b686a | ||
|
|
5c3c1bd0e7 | ||
|
|
696e5bb66f | ||
|
|
65540fbb5c | ||
|
|
351320491d | ||
|
|
d30700517d | ||
|
|
14ad8d0556 | ||
|
|
f04c97b587 | ||
|
|
b8d3038d38 | ||
|
|
eaa3604dce | ||
|
|
8acc348106 | ||
|
|
2567f2a787 | ||
|
|
84b5749c6b | ||
|
|
70d0049511 | ||
|
|
717f5929c2 | ||
|
|
81abb6c9d7 | ||
|
|
8bba3c8a14 | ||
|
|
b13e727b90 | ||
|
|
d352c9e66f | ||
|
|
c0aaba06d0 | ||
|
|
1633268d57 | ||
|
|
3bf1c2b820 | ||
|
|
4dbd2cb9fe | ||
|
|
65124a8d2e | ||
|
|
1b78f161f5 | ||
|
|
0ce259ada0 | ||
|
|
74da49f87f | ||
|
|
d5d697639c | ||
|
|
0b365ca7d3 | ||
|
|
db6f3d5d11 | ||
|
|
87be890e07 | ||
|
|
d72dc706d0 | ||
|
|
4cbbcd8f62 | ||
|
|
a2631ecacb | ||
|
|
4bcc5e8375 | ||
|
|
90f84000ba | ||
|
|
20a13754a7 | ||
|
|
aa7b9a3965 | ||
|
|
84ac1d10f3 | ||
|
|
0d623856a7 | ||
|
|
ec0d4e4e8c | ||
|
|
80ea736b3f | ||
|
|
ebaa5dfb51 | ||
|
|
f3bdf083fe | ||
|
|
1ce54a9cf9 | ||
|
|
6383a93ce7 | ||
|
|
01aa2ef5b2 | ||
|
|
819351f5a4 | ||
|
|
2967cebfb3 | ||
|
|
32e9a2c1c7 | ||
|
|
8e0a40a1aa | ||
|
|
e460826084 | ||
|
|
aa3445f38c | ||
|
|
408b7bf35e | ||
|
|
6185dfee14 | ||
|
|
37aa2739a5 | ||
|
|
d061c33a16 | ||
|
|
0c7d2d07d4 | ||
|
|
62cf4373bd | ||
|
|
a74ad23514 | ||
|
|
2d9b4992ec | ||
|
|
82e8c1e68b | ||
|
|
46be054ce9 | ||
|
|
789d784769 | ||
|
|
81deb8efde | ||
|
|
072dccd05d | ||
|
|
637c99d637 | ||
|
|
0f48852730 | ||
|
|
0499b2907d | ||
|
|
61e69c9251 | ||
|
|
4a560ea1e5 | ||
|
|
c5b6ee6f81 | ||
|
|
1a7bf63622 | ||
|
|
8847cdc0a9 | ||
|
|
c82e76a111 | ||
|
|
4db486d76d | ||
|
|
91966a6917 | ||
|
|
b3917aaadf | ||
|
|
ba307003c4 | ||
|
|
21fd1271d9 | ||
|
|
f9ab7d6f56 | ||
|
|
0a3a41a708 | ||
|
|
6c2a536fa5 | ||
|
|
26eced3640 | ||
|
|
6f950c9ec8 | ||
|
|
ea13e40889 | ||
|
|
595fb1aef3 | ||
|
|
18986978fb | ||
|
|
c3cb22a789 | ||
|
|
5aebd6b562 | ||
|
|
4c13085b35 | ||
|
|
8709e8a14e | ||
|
|
9eea46ec01 | ||
|
|
2e9f937c43 | ||
|
|
65b10b6537 | ||
|
|
b51a8d5966 | ||
|
|
55e3d70869 | ||
|
|
20ba57e389 | ||
|
|
39bc3c64fe | ||
|
|
40ccf1d912 | ||
|
|
982ae36428 | ||
|
|
d6714ec450 | ||
|
|
773c3816be | ||
|
|
1b417ddc7a | ||
|
|
7a0ecf977d | ||
|
|
aade704411 | ||
|
|
ca3f6102ef | ||
|
|
4a58b629ce | ||
|
|
3adba237b8 | ||
|
|
ccf03d9291 | ||
|
|
30ae90ebd5 | ||
|
|
d5369c3429 | ||
|
|
48f2f0555d | ||
|
|
f40fd12e25 | ||
|
|
65c2c3c238 | ||
|
|
891a61a5e3 | ||
|
|
1e6f30f6fa | ||
|
|
02346a3126 | ||
|
|
1908f18e95 | ||
|
|
3bfa7f09ba | ||
|
|
243f43fafd | ||
|
|
66e27a94b6 | ||
|
|
227688ec63 | ||
|
|
e761a503c0 | ||
|
|
209ad79a8f | ||
|
|
cdf209d7f6 | ||
|
|
77ab391885 | ||
|
|
6628fe5ace | ||
|
|
f3e3000d45 | ||
|
|
f7380c6e32 | ||
|
|
d86870e038 | ||
|
|
0908806915 | ||
|
|
d17c192681 | ||
|
|
cad8f51256 | ||
|
|
43014c6619 | ||
|
|
30a41aa710 | ||
|
|
04bfeba3f2 | ||
|
|
190636b791 | ||
|
|
31e450f9af | ||
|
|
b1b72a94a8 | ||
|
|
6929bcdf78 | ||
|
|
fd063af7ce | ||
|
|
df6dcbc4ed | ||
|
|
9b8db6a225 | ||
|
|
76863cb27f | ||
|
|
514df99e40 | ||
|
|
055353a460 | ||
|
|
9eb4008d6d | ||
|
|
a04544637b | ||
|
|
4c7dc17b78 | ||
|
|
59aaaab436 | ||
|
|
61dfa4a2dc | ||
|
|
ca337a1110 | ||
|
|
510e10de95 | ||
|
|
0babe8d589 | ||
|
|
5b2ce26721 | ||
|
|
db4d99cd4f | ||
|
|
74ceceef73 | ||
|
|
360e890cc0 | ||
|
|
46b35870c5 | ||
|
|
dddcecb034 | ||
|
|
c4c416e8b2 | ||
|
|
6693ec78f4 | ||
|
|
dc112bd6c1 | ||
|
|
084e82a8a9 | ||
|
|
f5079a7892 | ||
|
|
d90ffb63c6 | ||
|
|
b0ed122214 | ||
|
|
d88521d63c | ||
|
|
2accc9d22c | ||
|
|
363927f489 | ||
|
|
ae793fb631 | ||
|
|
944b83642a | ||
|
|
5a8e5dee73 | ||
|
|
7f870d5861 | ||
|
|
536b23dc84 | ||
|
|
0c9806e99f | ||
|
|
5a92932019 | ||
|
|
e929d2f00f | ||
|
|
1e1e4c06e8 | ||
|
|
d0726db473 | ||
|
|
4cdc15a824 | ||
|
|
b36fdf2f54 | ||
|
|
73ba6b385f | ||
|
|
30d1639aa4 | ||
|
|
d82814fc86 | ||
|
|
2220efd682 | ||
|
|
679b365cf7 | ||
|
|
83bf83b6dd | ||
|
|
321364c7c2 | ||
|
|
d8707d5867 | ||
|
|
2dd0a78c52 | ||
|
|
d7b8c3c78f | ||
|
|
2f0148a2df | ||
|
|
4accc29984 | ||
|
|
19b9af2494 | ||
|
|
0aa50e9439 | ||
|
|
a00a906482 | ||
|
|
19ad7d7c96 | ||
|
|
251e55da42 | ||
|
|
32f1b2060a | ||
|
|
b1c54532df | ||
|
|
38c67f16e8 | ||
|
|
24aefc52a1 | ||
|
|
ba8c205253 | ||
|
|
31193d99ba | ||
|
|
c4aecc8e4b | ||
|
|
60c81d06a0 | ||
|
|
46569da231 | ||
|
|
5e20a8ff16 | ||
|
|
dd9319245e | ||
|
|
4bbe42d105 | ||
|
|
5bdc022627 | ||
|
|
41e354f1ee | ||
|
|
d1c76709b0 | ||
|
|
64774a8db0 | ||
|
|
53f6b8268b | ||
|
|
32dcc35918 | ||
|
|
8c3854b28b | ||
|
|
75af9c79df | ||
|
|
1dfe32acd8 | ||
|
|
5dfdbe4bff | ||
|
|
4584eeb57a | ||
|
|
aa67069387 | ||
|
|
ee3424ad51 | ||
|
|
17def14ab6 | ||
|
|
51dd3abcae | ||
|
|
825b2c30a1 | ||
|
|
b5b8830c29 | ||
|
|
87a5c844c2 | ||
|
|
11c7ee4501 | ||
|
|
d24a188d4c | ||
|
|
29876221f8 | ||
|
|
7c03c446fe | ||
|
|
cfdd4d4a90 | ||
|
|
5546b3389d | ||
|
|
9c95992dad | ||
|
|
edb48b2872 | ||
|
|
c63ac7e435 | ||
|
|
fec49aaaa3 | ||
|
|
617187969c | ||
|
|
e3217cd572 | ||
|
|
4d02f399a2 | ||
|
|
24723226f1 | ||
|
|
7b3684b54e | ||
|
|
13c1f9c259 | ||
|
|
6df75ad28e | ||
|
|
74fc70cfee | ||
|
|
91ac2debce | ||
|
|
0de89a9f19 | ||
|
|
130609bf5f | ||
|
|
ab41e7acb9 | ||
|
|
c15bc8df4a | ||
|
|
19524dbc4b | ||
|
|
c2e733a65d | ||
|
|
0c08b9e940 | ||
|
|
06197605ba | ||
|
|
5c24cfd325 |
59
.circleci/config.yml
Normal file
59
.circleci/config.yml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
version: 2.1
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test_suite:
|
||||||
|
environment:
|
||||||
|
- GOPATH: /home/circleci/go
|
||||||
|
docker:
|
||||||
|
- image: circleci/golang:1.9
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
command: |
|
||||||
|
g++ --version
|
||||||
|
cd tests/
|
||||||
|
g++ -std=c++11 -O2 -Wall -Wextra -Werror -I../ check_toml_test.cpp -o check_toml_test
|
||||||
|
go get github.com/BurntSushi/toml-test
|
||||||
|
$GOPATH/bin/toml-test ./check_toml_test
|
||||||
|
output_result:
|
||||||
|
docker:
|
||||||
|
- image: circleci/buildpack-deps:bionic
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
command: |
|
||||||
|
g++ --version
|
||||||
|
cd tests/
|
||||||
|
g++ -std=c++11 -O2 -Wall -Wextra -Werror -I../ check.cpp -o check
|
||||||
|
git clone https://github.com/BurntSushi/toml-test.git
|
||||||
|
cp check toml-test/tests/invalid
|
||||||
|
cp check toml-test/tests/valid
|
||||||
|
cd toml-test/tests/invalid
|
||||||
|
for f in $(ls ./*.toml);
|
||||||
|
do echo "==> ${f}";
|
||||||
|
cat ${f};
|
||||||
|
echo "---------------------------------------";
|
||||||
|
./check ${f} invalid;
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "=======================================";
|
||||||
|
done
|
||||||
|
cd ../valid
|
||||||
|
for f in $(ls ./*.toml);
|
||||||
|
do echo "==> ${f}";
|
||||||
|
cat ${f};
|
||||||
|
echo "---------------------------------------";
|
||||||
|
./check ${f} valid;
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "=======================================";
|
||||||
|
done
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2.1
|
||||||
|
test:
|
||||||
|
jobs:
|
||||||
|
- test_suite
|
||||||
|
- output_result
|
||||||
160
.travis.yml
160
.travis.yml
@@ -5,38 +5,180 @@ matrix:
|
|||||||
- os: linux
|
- os: linux
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
env: COMPILER="g++-5"
|
env: COMPILER="g++-5" CXX_STANDARD=11
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
packages:
|
packages:
|
||||||
- g++-5
|
- g++-5
|
||||||
- build-essential
|
- boost1.70
|
||||||
- cmake
|
- os: linux
|
||||||
- libboost-all-dev
|
language: cpp
|
||||||
|
compiler: gcc
|
||||||
|
env: COMPILER="g++-6" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-6
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: gcc
|
||||||
|
env: COMPILER="g++-7" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-7
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: gcc
|
||||||
|
env: COMPILER="g++-8" CXX_STANDARD=11
|
||||||
|
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
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-8
|
||||||
|
- boost1.70
|
||||||
- os: linux
|
- os: linux
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env: COMPILER="clang++-3.7"
|
env: COMPILER="clang++-3.7" CXX_STANDARD=11
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- llvm-toolchain-precise-3.7
|
- llvm-toolchain-precise-3.7
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
packages:
|
packages:
|
||||||
|
- g++-8
|
||||||
- clang-3.7
|
- clang-3.7
|
||||||
- build-essential
|
- boost1.70
|
||||||
- cmake
|
- os: linux
|
||||||
- libboost-all-dev
|
language: cpp
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER="clang++-4.0" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-4.0
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-8
|
||||||
|
- clang-4.0
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER="clang++-5.0" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-5.0
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-8
|
||||||
|
- clang-5.0
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER="clang++-6.0" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-6.0
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-8
|
||||||
|
- clang-6.0
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER="clang++-7" CXX_STANDARD=11
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-7
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- g++-8
|
||||||
|
- clang-7
|
||||||
|
- boost1.70
|
||||||
|
- os: linux
|
||||||
|
language: cpp
|
||||||
|
compiler: clang
|
||||||
|
env: COMPILER="clang++-8" CXX_STANDARD=11
|
||||||
|
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
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
|
- llvm-toolchain-trusty-8
|
||||||
|
- sourceline: 'ppa:mhier/libboost-latest'
|
||||||
|
packages:
|
||||||
|
- clang-8
|
||||||
|
- g++-8
|
||||||
|
- boost1.70
|
||||||
- os: osx
|
- os: osx
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
env: CXX_STANDARD=11
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- |
|
||||||
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
|
mkdir -p cmake
|
||||||
|
travis_retry wget "https://github.com/Kitware/CMake/releases/download/v3.14.5/cmake-3.14.5-Linux-x86_64.tar.gz"
|
||||||
|
tar xf cmake-3.14.5-Linux-x86_64.tar.gz -C cmake --strip-components=1
|
||||||
|
export PATH=${TRAVIS_BUILD_DIR}/cmake/bin:${PATH}
|
||||||
|
else
|
||||||
|
brew upgrade cmake boost
|
||||||
|
fi
|
||||||
|
- cmake --version
|
||||||
- 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 ..
|
- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD ..
|
||||||
- make
|
- make
|
||||||
- ctest --output-on-failure
|
- ctest --output-on-failure
|
||||||
|
|||||||
@@ -1,10 +1,23 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
project(toml11)
|
project(toml11)
|
||||||
|
|
||||||
|
set(toml11_VERSION_MAYOR 2)
|
||||||
|
set(toml11_VERSION_MINOR 4)
|
||||||
|
set(toml11_VERSION_PATCH 0)
|
||||||
|
set(toml11_VERSION
|
||||||
|
"${toml11_VERSION_MAYOR}.${toml11_VERSION_MINOR}.${toml11_VERSION_PATCH}"
|
||||||
|
)
|
||||||
|
|
||||||
|
option(toml11_BUILD_TEST "Build toml tests" ON)
|
||||||
|
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
if("${CMAKE_VERSION}" VERSION_GREATER 3.1)
|
if("${CMAKE_VERSION}" VERSION_GREATER 3.1)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
if(NOT DEFINED CMAKE_CXX_STANDARD)
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
endif()
|
||||||
set(CXX_STANDARD_REQUIRED ON)
|
set(CXX_STANDARD_REQUIRED ON)
|
||||||
else()
|
else()
|
||||||
# Manually check for C++11 compiler flag.
|
# Manually check for C++11 compiler flag.
|
||||||
@@ -31,5 +44,62 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR})
|
# Set some common directories
|
||||||
add_subdirectory(tests)
|
include(GNUInstallDirs)
|
||||||
|
set(toml11_install_cmake_dir ${CMAKE_INSTALL_LIBDIR}/cmake/toml11)
|
||||||
|
set(toml11_install_include_dir ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
set(toml11_config_dir ${CMAKE_CURRENT_BINARY_DIR}/cmake/)
|
||||||
|
set(toml11_config ${toml11_config_dir}/toml11Config.cmake)
|
||||||
|
set(toml11_config_version ${toml11_config_dir}/toml11ConfigVersion.cmake)
|
||||||
|
|
||||||
|
add_library(toml11 INTERFACE)
|
||||||
|
target_include_directories(toml11 INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||||
|
$<INSTALL_INTERFACE:${toml11_install_include_dir}>
|
||||||
|
)
|
||||||
|
add_library(toml11::toml11 ALIAS toml11)
|
||||||
|
|
||||||
|
# Write config and version config files
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
write_basic_package_version_file(
|
||||||
|
${toml11_config_version}
|
||||||
|
VERSION ${toml11_VERSION}
|
||||||
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_package_config_file(
|
||||||
|
cmake/toml11Config.cmake.in
|
||||||
|
${toml11_config}
|
||||||
|
INSTALL_DESTINATION ${toml11_install_cmake_dir}
|
||||||
|
PATH_VARS toml11_install_cmake_dir
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install config files
|
||||||
|
install(FILES ${toml11_config} ${toml11_config_version}
|
||||||
|
DESTINATION ${toml11_install_cmake_dir}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install header files
|
||||||
|
install(
|
||||||
|
FILES toml.hpp
|
||||||
|
DESTINATION "${toml11_install_include_dir}"
|
||||||
|
)
|
||||||
|
install(
|
||||||
|
DIRECTORY "toml"
|
||||||
|
DESTINATION "${toml11_install_include_dir}"
|
||||||
|
FILES_MATCHING PATTERN "*.hpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Export targets and install them
|
||||||
|
install(TARGETS toml11
|
||||||
|
EXPORT toml11Targets
|
||||||
|
)
|
||||||
|
install(EXPORT toml11Targets
|
||||||
|
FILE toml11Targets.cmake
|
||||||
|
DESTINATION ${toml11_install_cmake_dir}
|
||||||
|
NAMESPACE toml11::
|
||||||
|
)
|
||||||
|
|
||||||
|
if (toml11_BUILD_TEST)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif ()
|
||||||
|
|||||||
59
PROPOSAL.md
59
PROPOSAL.md
@@ -1,59 +0,0 @@
|
|||||||
|
|
||||||
### encoding user's data
|
|
||||||
|
|
||||||
You can encode your data to toml format.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
const toml::value integer(1);
|
|
||||||
const toml::value array{3.1, 3.14, 3.141, 3.1415};
|
|
||||||
const toml::value table{{"answer", 42}, {"pi", 3.14}, {"string", "foobar"}};
|
|
||||||
|
|
||||||
std::cout << toml::format("integer", integer) << std::endl;
|
|
||||||
std::cout << toml::format("array", array) << std::endl;
|
|
||||||
std::cout << toml::format("table", table) << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
this program will output as below.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
integer = 1
|
|
||||||
array = [3.1, 3.14, 3.141, 3.1415]
|
|
||||||
[table]
|
|
||||||
answer = 42
|
|
||||||
pi = 3.14
|
|
||||||
string = "foobar"
|
|
||||||
```
|
|
||||||
|
|
||||||
Without key name, you can make string formatted as toml.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
const std::string integer_ = toml::format(integer); // "1"
|
|
||||||
const std::string array_ = toml::format(array); // "[3.1, 3.14, 3.141, 3.1415]"
|
|
||||||
const std::string table_ = toml::format(table); // "answer = 42\npi=3.14\nstring=foobar"
|
|
||||||
```
|
|
||||||
|
|
||||||
### inlinize
|
|
||||||
|
|
||||||
You can make `toml::Table` inline.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
const toml::value table{{"answer", 42}, {"pi", 3.14}, {"string", "foobar"}};
|
|
||||||
// if the inline-table format length is less than 80, the table will be inlined
|
|
||||||
std::cout << toml::format("table", table, toml::make_inline(80)) << std::endl;
|
|
||||||
// In any case, the table will be inlined.
|
|
||||||
std::cout << toml::format("table", table, toml::forceinline) << std::endl;
|
|
||||||
```
|
|
||||||
|
|
||||||
```toml
|
|
||||||
table = {answer = 42, pi = 3.14, string = "foobar"}
|
|
||||||
```
|
|
||||||
|
|
||||||
And there are some stream manipulators for toml format.
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
const toml::value table{{"answer", 42}, {"pi", 3.14}, {"string", "foobar"}};
|
|
||||||
// if the inline-table format length is less than 80, the table will be inlined
|
|
||||||
std::cout << toml::make_inline(80) << table << std::endl;
|
|
||||||
// In any case, the table will be inlined.
|
|
||||||
std::cout << toml::forceinline << table << std::endl;
|
|
||||||
```
|
|
||||||
@@ -19,7 +19,7 @@ build_script:
|
|||||||
- cd build
|
- cd build
|
||||||
- git clone https://github.com/toml-lang/toml.git
|
- git clone https://github.com/toml-lang/toml.git
|
||||||
- file --mime-encoding toml/tests/hard_example_unicode.toml
|
- file --mime-encoding toml/tests/hard_example_unicode.toml
|
||||||
- cmake -G"%generator%" -DBOOST_ROOT=C:/Libraries/boost_1_63_0 ..
|
- cmake -G"%generator%" -DBOOST_ROOT=C:/Libraries/boost_1_69_0 ..
|
||||||
- cmake --build . --config "%configuration%"
|
- cmake --build . --config "%configuration%"
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
|
|||||||
2
cmake/toml11Config.cmake.in
Normal file
2
cmake/toml11Config.cmake.in
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
@PACKAGE_INIT@
|
||||||
|
include("@PACKAGE_toml11_install_cmake_dir@/toml11Targets.cmake")
|
||||||
@@ -20,21 +20,31 @@ set(TEST_NAMES
|
|||||||
test_parse_inline_table
|
test_parse_inline_table
|
||||||
test_parse_key
|
test_parse_key
|
||||||
test_parse_table_key
|
test_parse_table_key
|
||||||
|
test_literals
|
||||||
|
test_comments
|
||||||
test_get
|
test_get
|
||||||
test_get_related_func
|
test_get_or
|
||||||
test_to_toml
|
test_find
|
||||||
test_from_toml
|
test_find_or
|
||||||
|
test_expect
|
||||||
test_parse_file
|
test_parse_file
|
||||||
|
test_serialize_file
|
||||||
test_parse_unicode
|
test_parse_unicode
|
||||||
)
|
test_error_detection
|
||||||
|
test_format_error
|
||||||
|
test_extended_conversions
|
||||||
|
)
|
||||||
|
|
||||||
CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL)
|
CHECK_CXX_COMPILER_FLAG("-Wall" COMPILER_SUPPORTS_WALL)
|
||||||
|
CHECK_CXX_COMPILER_FLAG("-Wextra" COMPILER_SUPPORTS_WEXTRA)
|
||||||
CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC)
|
CHECK_CXX_COMPILER_FLAG("-Wpedantic" COMPILER_SUPPORTS_WPEDANTIC)
|
||||||
|
|
||||||
if(COMPILER_SUPPORTS_WALL)
|
if(COMPILER_SUPPORTS_WALL)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
endif()
|
endif()
|
||||||
|
if(COMPILER_SUPPORTS_WEXTRA)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
|
||||||
|
endif()
|
||||||
if(COMPILER_SUPPORTS_WPEDANTIC)
|
if(COMPILER_SUPPORTS_WPEDANTIC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")
|
||||||
endif()
|
endif()
|
||||||
@@ -83,7 +93,7 @@ add_definitions(-DUNITTEST_FRAMEWORK_LIBRARY_EXIST)
|
|||||||
|
|
||||||
foreach(TEST_NAME ${TEST_NAMES})
|
foreach(TEST_NAME ${TEST_NAMES})
|
||||||
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
|
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
|
||||||
target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
|
target_link_libraries(${TEST_NAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} toml11::toml11)
|
||||||
target_include_directories(${TEST_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
|
target_include_directories(${TEST_NAME} PRIVATE ${Boost_INCLUDE_DIRS})
|
||||||
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||||
|
|
||||||
@@ -95,3 +105,9 @@ foreach(TEST_NAME ${TEST_NAMES})
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
endforeach(TEST_NAME)
|
endforeach(TEST_NAME)
|
||||||
|
|
||||||
|
# this test is to check it compiles. it will not run
|
||||||
|
add_executable(test_multiple_translation_unit
|
||||||
|
test_multiple_translation_unit_1.cpp
|
||||||
|
test_multiple_translation_unit_2.cpp)
|
||||||
|
target_link_libraries(test_multiple_translation_unit toml11::toml11)
|
||||||
|
|||||||
41
tests/check.cpp
Normal file
41
tests/check.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include "toml.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if(argc != 3)
|
||||||
|
{
|
||||||
|
std::cerr << "usage: ./check [filename] [valid|invalid]" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string file_kind(argv[2]);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const auto data = toml::parse(argv[1]);
|
||||||
|
std::cout << std::setprecision(16) << std::setw(80) << data;
|
||||||
|
if(file_kind == "valid")
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(const toml::syntax_error& err)
|
||||||
|
{
|
||||||
|
std::cout << "what(): " << err.what() << std::endl;
|
||||||
|
if(file_kind == "invalid")
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 127;
|
||||||
|
}
|
||||||
142
tests/check_toml_test.cpp
Normal file
142
tests/check_toml_test.cpp
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
#include "toml.hpp"
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
struct json_serializer
|
||||||
|
{
|
||||||
|
void operator()(toml::boolean v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"bool\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(toml::integer v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"integer\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(toml::floating v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"float\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::string& v)
|
||||||
|
{
|
||||||
|
// since toml11 automatically convert string to multiline string that is
|
||||||
|
// valid only in TOML, we need to format the string to make it valid in
|
||||||
|
// JSON.
|
||||||
|
std::cout << "{\"type\":\"string\",\"value\":\""
|
||||||
|
<< this->escape_string(v.str) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::local_time& v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"local_time\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::local_date& v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"local_date\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::local_datetime& v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"local_datetime\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::offset_datetime& v)
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"datetime\",\"value\":\"" << toml::value(v) << "\"}";
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::array& v)
|
||||||
|
{
|
||||||
|
if(!v.empty() && v.front().is_table())
|
||||||
|
{
|
||||||
|
std::cout << '[';
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto& elem : v)
|
||||||
|
{
|
||||||
|
if(!is_first) {std::cout << ", ";}
|
||||||
|
is_first = false;
|
||||||
|
toml::visit(*this, elem);
|
||||||
|
}
|
||||||
|
std::cout << ']';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "{\"type\":\"array\",\"value\":[";
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto& elem : v)
|
||||||
|
{
|
||||||
|
if(!is_first) {std::cout << ", ";}
|
||||||
|
is_first = false;
|
||||||
|
toml::visit(*this, elem);
|
||||||
|
}
|
||||||
|
std::cout << "]}";
|
||||||
|
}
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
void operator()(const toml::table& v)
|
||||||
|
{
|
||||||
|
std::cout << '{';
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto& elem : v)
|
||||||
|
{
|
||||||
|
if(!is_first) {std::cout << ", ";}
|
||||||
|
is_first = false;
|
||||||
|
std::cout << toml::format(toml::value(elem.first),
|
||||||
|
std::numeric_limits<std::size_t>::max());
|
||||||
|
std::cout << ':';
|
||||||
|
toml::visit(*this, elem.second);
|
||||||
|
}
|
||||||
|
std::cout << '}';
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string escape_string(const std::string& s) const
|
||||||
|
{
|
||||||
|
std::string retval;
|
||||||
|
for(const char c : s)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case '\\': {retval += "\\\\"; break;}
|
||||||
|
case '\"': {retval += "\\\""; break;}
|
||||||
|
case '\b': {retval += "\\b"; break;}
|
||||||
|
case '\t': {retval += "\\t"; break;}
|
||||||
|
case '\f': {retval += "\\f"; break;}
|
||||||
|
case '\n': {retval += "\\n"; break;}
|
||||||
|
case '\r': {retval += "\\r"; break;}
|
||||||
|
default : {retval += c; break;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::vector<char> buf;
|
||||||
|
std::cin.peek();
|
||||||
|
while(!std::cin.eof())
|
||||||
|
{
|
||||||
|
buf.push_back(std::cin.get());
|
||||||
|
std::cin.peek();
|
||||||
|
}
|
||||||
|
std::string bufstr(buf.begin(), buf.end());
|
||||||
|
|
||||||
|
std::istringstream ss(bufstr);
|
||||||
|
|
||||||
|
const auto data = toml::parse(ss);
|
||||||
|
std::cout << std::setprecision(std::numeric_limits<double>::max_digits10);
|
||||||
|
toml::visit(json_serializer(), data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch(const toml::syntax_error& err)
|
||||||
|
{
|
||||||
|
std::cout << "what(): " << err.what() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
462
tests/test_comments.cpp
Normal file
462
tests/test_comments.cpp
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_comments"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <toml.hpp>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_comment_before)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
# comment for a.
|
||||||
|
a = 42
|
||||||
|
# comment for b.
|
||||||
|
b = "baz"
|
||||||
|
)";
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse<toml::preserve_comments>(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().size() == 1u);
|
||||||
|
BOOST_TEST(a.comments().front() == u8" comment for a.");
|
||||||
|
BOOST_TEST(b.comments().size() == 1u);
|
||||||
|
BOOST_TEST(b.comments().front() == u8" comment for b.");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
# comment for a.
|
||||||
|
# another comment for a.
|
||||||
|
a = 42
|
||||||
|
# comment for b.
|
||||||
|
# also comment for b.
|
||||||
|
b = "baz"
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse<toml::preserve_comments>(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().size() == 2u);
|
||||||
|
BOOST_TEST(a.comments().front() == u8" comment for a.");
|
||||||
|
BOOST_TEST(a.comments().back() == u8" another comment for a.");
|
||||||
|
BOOST_TEST(b.comments().size() == 2u);
|
||||||
|
BOOST_TEST(b.comments().front() == u8" comment for b.");
|
||||||
|
BOOST_TEST(b.comments().back() == u8" also comment for b.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_comment_inline)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
a = 42 # comment for a.
|
||||||
|
b = "baz" # comment for b.
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse<toml::preserve_comments>(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().size() == 1u);
|
||||||
|
BOOST_TEST(a.comments().front() == u8" comment for a.");
|
||||||
|
BOOST_TEST(b.comments().size() == 1u);
|
||||||
|
BOOST_TEST(b.comments().front() == u8" comment for b.");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
a = [
|
||||||
|
42,
|
||||||
|
] # comment for a.
|
||||||
|
b = [
|
||||||
|
"bar", # this is not a comment for b, but "bar"
|
||||||
|
] # this is a comment for b.
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse<toml::preserve_comments>(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
const auto& b0 = b.as_array().at(0);
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().size() == 1u);
|
||||||
|
BOOST_TEST(a.comments().front() == u8" comment for a.");
|
||||||
|
BOOST_TEST(b.comments().size() == 1u);
|
||||||
|
BOOST_TEST(b.comments().front() == u8" this is a comment for b.");
|
||||||
|
BOOST_TEST(b0.comments().size() == 1u);
|
||||||
|
BOOST_TEST(b0.comments().front() == u8" this is not a comment for b, but \"bar\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_comment_both)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
# comment for a.
|
||||||
|
a = 42 # inline comment for a.
|
||||||
|
# comment for b.
|
||||||
|
b = "baz" # inline comment for b.
|
||||||
|
# comment for c.
|
||||||
|
c = [ # this comment will be ignored
|
||||||
|
# comment for the first element.
|
||||||
|
10 # this also.
|
||||||
|
] # another comment for c.
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse<toml::preserve_comments>(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
const auto& c = toml::find(v, "c");
|
||||||
|
const auto& c0 = c.as_array().at(0);
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().size() == 2u);
|
||||||
|
BOOST_TEST(a.comments().front() == u8" comment for a.");
|
||||||
|
BOOST_TEST(a.comments().back() == u8" inline comment for a.");
|
||||||
|
BOOST_TEST(b.comments().size() == 2u);
|
||||||
|
BOOST_TEST(b.comments().front() == u8" comment for b.");
|
||||||
|
BOOST_TEST(b.comments().back() == u8" inline comment for b.");
|
||||||
|
|
||||||
|
BOOST_TEST(c.comments().size() == 2u);
|
||||||
|
BOOST_TEST(c.comments().front() == u8" comment for c.");
|
||||||
|
BOOST_TEST(c.comments().back() == u8" another comment for c.");
|
||||||
|
|
||||||
|
BOOST_TEST(c0.comments().size() == 2u);
|
||||||
|
BOOST_TEST(c0.comments().front() == u8" comment for the first element.");
|
||||||
|
BOOST_TEST(c0.comments().back() == u8" this also.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_discard_comment)
|
||||||
|
{
|
||||||
|
const std::string file = u8R"(
|
||||||
|
# comment for a.
|
||||||
|
a = 42 # inline comment for a.
|
||||||
|
# comment for b.
|
||||||
|
b = "baz" # inline comment for b.
|
||||||
|
# comment for c.
|
||||||
|
c = [ # this comment will be ignored
|
||||||
|
# comment for the first element.
|
||||||
|
10 # this also.
|
||||||
|
] # another comment for c.
|
||||||
|
)";
|
||||||
|
|
||||||
|
std::istringstream iss(file);
|
||||||
|
const auto v = toml::parse(iss);
|
||||||
|
|
||||||
|
const auto& a = toml::find(v, "a");
|
||||||
|
const auto& b = toml::find(v, "b");
|
||||||
|
const auto& c = toml::find(v, "c");
|
||||||
|
const auto& c0 = c.as_array().at(0);
|
||||||
|
|
||||||
|
BOOST_TEST(a.comments().empty());
|
||||||
|
BOOST_TEST(b.comments().empty());
|
||||||
|
BOOST_TEST(c.comments().empty());
|
||||||
|
BOOST_TEST(c0.comments().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_construct_value_with_comments)
|
||||||
|
{
|
||||||
|
using value_type = toml::basic_value<toml::preserve_comments>;
|
||||||
|
{
|
||||||
|
const value_type v(true, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_boolean());
|
||||||
|
BOOST_TEST(v.as_boolean() == true);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(42, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_integer());
|
||||||
|
BOOST_TEST(v.as_integer() == 42);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(3.14, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_floating());
|
||||||
|
BOOST_TEST(v.as_floating() == 3.14);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(toml::string("str"), {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(std::string("str"), {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(std::string("str"), toml::string_t::literal,
|
||||||
|
{"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v("str", {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v("str", toml::string_t::literal,
|
||||||
|
{"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
{
|
||||||
|
using namespace std::literals::string_view_literals;
|
||||||
|
const value_type v("str"sv, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using namespace std::literals::string_view_literals;
|
||||||
|
const value_type v("str"sv, toml::string_t::literal,
|
||||||
|
{"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_string());
|
||||||
|
BOOST_TEST(v.as_string() == "str");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
const toml::local_date ld{2019, toml::month_t::Apr, 1};
|
||||||
|
const toml::local_time lt{12, 30, 45};
|
||||||
|
const toml::local_datetime ldt{ld, lt};
|
||||||
|
const toml::offset_datetime odt{ld, lt, toml::time_offset{9, 0}};
|
||||||
|
{
|
||||||
|
const value_type v(ld, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_local_date());
|
||||||
|
BOOST_TEST(v.as_local_date() == ld);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(lt, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_local_time());
|
||||||
|
BOOST_TEST(v.as_local_time() == lt);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::local_time three_hours{3,0,0};
|
||||||
|
const value_type v(std::chrono::hours(3), {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_local_time());
|
||||||
|
BOOST_TEST(v.as_local_time() == three_hours);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(ldt, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_local_datetime());
|
||||||
|
BOOST_TEST(v.as_local_datetime() == ldt);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(odt, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_offset_datetime());
|
||||||
|
BOOST_TEST(v.as_offset_datetime() == odt);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto systp = static_cast<std::chrono::system_clock::time_point>(odt);
|
||||||
|
const value_type v(systp, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_offset_datetime());
|
||||||
|
|
||||||
|
// While the conversion, the information about time offset may change.
|
||||||
|
const auto systp2 = static_cast<std::chrono::system_clock::time_point>(
|
||||||
|
v.as_offset_datetime());
|
||||||
|
const bool result = systp == systp2; // because there is no operator<<
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const typename value_type::array_type a{1,2,3,4,5};
|
||||||
|
const value_type v(a, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_array());
|
||||||
|
BOOST_TEST(v.as_array().at(0).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(1).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(2).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(3).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(4).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(0).as_integer() == 1);
|
||||||
|
BOOST_TEST(v.as_array().at(1).as_integer() == 2);
|
||||||
|
BOOST_TEST(v.as_array().at(2).as_integer() == 3);
|
||||||
|
BOOST_TEST(v.as_array().at(3).as_integer() == 4);
|
||||||
|
BOOST_TEST(v.as_array().at(4).as_integer() == 5);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::initializer_list<int> a = {1,2,3,4,5};
|
||||||
|
const value_type v(a, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_array());
|
||||||
|
BOOST_TEST(v.as_array().at(0).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(1).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(2).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(3).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(4).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(0).as_integer() == 1);
|
||||||
|
BOOST_TEST(v.as_array().at(1).as_integer() == 2);
|
||||||
|
BOOST_TEST(v.as_array().at(2).as_integer() == 3);
|
||||||
|
BOOST_TEST(v.as_array().at(3).as_integer() == 4);
|
||||||
|
BOOST_TEST(v.as_array().at(4).as_integer() == 5);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::vector<int> a = {1,2,3,4,5};
|
||||||
|
const value_type v(a, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_array());
|
||||||
|
BOOST_TEST(v.as_array().at(0).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(1).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(2).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(3).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(4).is_integer());
|
||||||
|
BOOST_TEST(v.as_array().at(0).as_integer() == 1);
|
||||||
|
BOOST_TEST(v.as_array().at(1).as_integer() == 2);
|
||||||
|
BOOST_TEST(v.as_array().at(2).as_integer() == 3);
|
||||||
|
BOOST_TEST(v.as_array().at(3).as_integer() == 4);
|
||||||
|
BOOST_TEST(v.as_array().at(4).as_integer() == 5);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const typename value_type::table_type t{
|
||||||
|
{"key1", 42}, {"key2", "foobar"}
|
||||||
|
};
|
||||||
|
const value_type v(t, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_table());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").is_integer());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").as_integer() == 42);
|
||||||
|
BOOST_TEST(v.as_table().at("key2").is_string());
|
||||||
|
BOOST_TEST(v.as_table().at("key2").as_string() == "foobar");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::initializer_list<std::pair<std::string, value_type>> t{
|
||||||
|
{"key1", 42}, {"key2", "foobar"}
|
||||||
|
};
|
||||||
|
const value_type v(t, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_table());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").is_integer());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").as_integer() == 42);
|
||||||
|
BOOST_TEST(v.as_table().at("key2").is_string());
|
||||||
|
BOOST_TEST(v.as_table().at("key2").as_string() == "foobar");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::map<std::string, value_type> t{
|
||||||
|
{"key1", 42}, {"key2", "foobar"}
|
||||||
|
};
|
||||||
|
const value_type v(t, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_table());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").is_integer());
|
||||||
|
BOOST_TEST(v.as_table().at("key1").as_integer() == 42);
|
||||||
|
BOOST_TEST(v.as_table().at("key2").is_string());
|
||||||
|
BOOST_TEST(v.as_table().at("key2").as_string() == "foobar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_overwrite_comments)
|
||||||
|
{
|
||||||
|
using value_type = toml::basic_value<toml::preserve_comments>;
|
||||||
|
{
|
||||||
|
const value_type v(42, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_integer());
|
||||||
|
BOOST_TEST(v.as_integer() == 42);
|
||||||
|
|
||||||
|
const value_type u(v, {"comment3", "comment4"});
|
||||||
|
BOOST_TEST(u.comments().size() == 2u);
|
||||||
|
BOOST_TEST(u.comments().at(0) == "comment3");
|
||||||
|
BOOST_TEST(u.comments().at(1) == "comment4");
|
||||||
|
BOOST_TEST(u.is_integer());
|
||||||
|
BOOST_TEST(u.as_integer() == 42);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(42, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_integer());
|
||||||
|
BOOST_TEST(v.as_integer() == 42);
|
||||||
|
|
||||||
|
const value_type u(v);
|
||||||
|
BOOST_TEST(u.comments().size() == 2u);
|
||||||
|
BOOST_TEST(u.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(u.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(u.is_integer());
|
||||||
|
BOOST_TEST(u.as_integer() == 42);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const value_type v(42, {"comment1", "comment2"});
|
||||||
|
BOOST_TEST(v.comments().size() == 2u);
|
||||||
|
BOOST_TEST(v.comments().at(0) == "comment1");
|
||||||
|
BOOST_TEST(v.comments().at(1) == "comment2");
|
||||||
|
BOOST_TEST(v.is_integer());
|
||||||
|
BOOST_TEST(v.as_integer() == 42);
|
||||||
|
|
||||||
|
const value_type u(v, {});
|
||||||
|
BOOST_TEST(u.comments().size() == 0u);
|
||||||
|
BOOST_TEST(u.is_integer());
|
||||||
|
BOOST_TEST(u.as_integer() == 42);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,47 +11,47 @@ BOOST_AUTO_TEST_CASE(test_local_date)
|
|||||||
{
|
{
|
||||||
const toml::local_date date(2018, toml::month_t::Jan, 1);
|
const toml::local_date date(2018, toml::month_t::Jan, 1);
|
||||||
const toml::local_date date1(date);
|
const toml::local_date date1(date);
|
||||||
BOOST_CHECK_EQUAL(date, date1);
|
BOOST_TEST(date == date1);
|
||||||
|
|
||||||
const std::chrono::system_clock::time_point tp(date);
|
const std::chrono::system_clock::time_point tp(date);
|
||||||
const toml::local_date date2(tp);
|
const toml::local_date date2(tp);
|
||||||
BOOST_CHECK_EQUAL(date, date2);
|
BOOST_TEST(date == date2);
|
||||||
|
|
||||||
const toml::local_date date3(2017, toml::month_t::Dec, 31);
|
const toml::local_date date3(2017, toml::month_t::Dec, 31);
|
||||||
BOOST_CHECK(date > date3);
|
BOOST_TEST(date > date3);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << date;
|
oss << date;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("2018-01-01"));
|
BOOST_TEST(oss.str() == std::string("2018-01-01"));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_local_time)
|
BOOST_AUTO_TEST_CASE(test_local_time)
|
||||||
{
|
{
|
||||||
const toml::local_time time(12, 30, 45);
|
const toml::local_time time(12, 30, 45);
|
||||||
const toml::local_time time1(time);
|
const toml::local_time time1(time);
|
||||||
BOOST_CHECK_EQUAL(time, time1);
|
BOOST_TEST(time == time1);
|
||||||
|
|
||||||
const std::chrono::nanoseconds dur(time);
|
const std::chrono::nanoseconds dur(time);
|
||||||
std::chrono::nanoseconds ns(0);
|
std::chrono::nanoseconds ns(0);
|
||||||
ns += std::chrono::hours (12);
|
ns += std::chrono::hours (12);
|
||||||
ns += std::chrono::minutes(30);
|
ns += std::chrono::minutes(30);
|
||||||
ns += std::chrono::seconds(45);
|
ns += std::chrono::seconds(45);
|
||||||
BOOST_CHECK_EQUAL(dur.count(), ns.count());
|
BOOST_TEST(dur.count() == ns.count());
|
||||||
|
|
||||||
const toml::local_time time3(12, 15, 45);
|
const toml::local_time time3(12, 15, 45);
|
||||||
BOOST_CHECK(time > time3);
|
BOOST_TEST(time > time3);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << time;
|
oss << time;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("12:30:45"));
|
BOOST_TEST(oss.str() == std::string("12:30:45"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const toml::local_time time4(12, 30, 45, 123, 456);
|
const toml::local_time time4(12, 30, 45, 123, 456);
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << time4;
|
oss << time4;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("12:30:45.123456"));
|
BOOST_TEST(oss.str() == std::string("12:30:45.123456"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,20 +59,20 @@ BOOST_AUTO_TEST_CASE(test_time_offset)
|
|||||||
{
|
{
|
||||||
const toml::time_offset time(9, 30);
|
const toml::time_offset time(9, 30);
|
||||||
const toml::time_offset time1(time);
|
const toml::time_offset time1(time);
|
||||||
BOOST_CHECK_EQUAL(time, time1);
|
BOOST_TEST(time == time1);
|
||||||
|
|
||||||
const std::chrono::minutes dur(time);
|
const std::chrono::minutes dur(time);
|
||||||
std::chrono::minutes m(0);
|
std::chrono::minutes m(0);
|
||||||
m += std::chrono::hours (9);
|
m += std::chrono::hours (9);
|
||||||
m += std::chrono::minutes(30);
|
m += std::chrono::minutes(30);
|
||||||
BOOST_CHECK_EQUAL(dur.count(), m.count());
|
BOOST_TEST(dur.count() == m.count());
|
||||||
|
|
||||||
const toml::time_offset time2(9, 0);
|
const toml::time_offset time2(9, 0);
|
||||||
BOOST_CHECK(time2 < time);
|
BOOST_TEST(time2 < time);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << time;
|
oss << time;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("+09:30"));
|
BOOST_TEST(oss.str() == std::string("+09:30"));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_local_datetime)
|
BOOST_AUTO_TEST_CASE(test_local_datetime)
|
||||||
@@ -80,15 +80,15 @@ BOOST_AUTO_TEST_CASE(test_local_datetime)
|
|||||||
const toml::local_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1),
|
const toml::local_datetime dt(toml::local_date(2018, toml::month_t::Jan, 1),
|
||||||
toml::local_time(12, 30, 45));
|
toml::local_time(12, 30, 45));
|
||||||
const toml::local_datetime dt1(dt);
|
const toml::local_datetime dt1(dt);
|
||||||
BOOST_CHECK_EQUAL(dt, dt1);
|
BOOST_TEST(dt == dt1);
|
||||||
|
|
||||||
const std::chrono::system_clock::time_point tp(dt);
|
const std::chrono::system_clock::time_point tp(dt);
|
||||||
const toml::local_datetime dt2(tp);
|
const toml::local_datetime dt2(tp);
|
||||||
BOOST_CHECK_EQUAL(dt, dt2);
|
BOOST_TEST(dt == dt2);
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << dt;
|
oss << dt;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("2018-01-01T12:30:45"));
|
BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45"));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_offset_datetime)
|
BOOST_AUTO_TEST_CASE(test_offset_datetime)
|
||||||
@@ -97,17 +97,18 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime)
|
|||||||
toml::local_time(12, 30, 45),
|
toml::local_time(12, 30, 45),
|
||||||
toml::time_offset(9, 30));
|
toml::time_offset(9, 30));
|
||||||
const toml::offset_datetime dt1(dt);
|
const toml::offset_datetime dt1(dt);
|
||||||
BOOST_CHECK_EQUAL(dt, dt1);
|
BOOST_TEST(dt == dt1);
|
||||||
|
|
||||||
const std::chrono::system_clock::time_point tp1(dt);
|
const std::chrono::system_clock::time_point tp1(dt);
|
||||||
const toml::offset_datetime dt2(tp1);
|
const toml::offset_datetime dt2(tp1);
|
||||||
const std::chrono::system_clock::time_point tp2(dt2);
|
const std::chrono::system_clock::time_point tp2(dt2);
|
||||||
BOOST_CHECK(tp1 == tp2);
|
const bool tp_same = (tp1 == tp2);
|
||||||
|
BOOST_TEST(tp_same);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << dt;
|
oss << dt;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("2018-01-01T12:30:45+09:30"));
|
BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45+09:30"));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::offset_datetime dt3(
|
const toml::offset_datetime dt3(
|
||||||
@@ -116,6 +117,6 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime)
|
|||||||
toml::time_offset(0, 0));
|
toml::time_offset(0, 0));
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << dt3;
|
oss << dt3;
|
||||||
BOOST_CHECK_EQUAL(oss.str(), std::string("2018-01-01T12:30:45Z"));
|
BOOST_TEST(oss.str() == std::string("2018-01-01T12:30:45Z"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
97
tests/test_error_detection.cpp
Normal file
97
tests/test_error_detection.cpp
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_error_detection"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_empty_key)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string("= \"value\""));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_missing_value)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string("a ="));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_too_many_value)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string("a = 1 = \"value\""));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_duplicate_table)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"[table]\n"
|
||||||
|
"a = 42\n"
|
||||||
|
"[table]\n"
|
||||||
|
"b = 42\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_conflict_array_table)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"[[table]]\n"
|
||||||
|
"a = 42\n"
|
||||||
|
"[table]\n"
|
||||||
|
"b = 42\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_conflict_table_array)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"[table]\n"
|
||||||
|
"a = 42\n"
|
||||||
|
"[[table]]\n"
|
||||||
|
"b = 42\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_duplicate_value)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"a = 1\n"
|
||||||
|
"a = 2\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_conflicting_value)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"a.b = 1\n"
|
||||||
|
"a.b.c = 2\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"a = [1, 1.0]\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_detect_appending_array_of_table)
|
||||||
|
{
|
||||||
|
std::istringstream stream(std::string(
|
||||||
|
"a = [{b = 1}]\n"
|
||||||
|
"[[a]]\n"
|
||||||
|
"b = 2\n"
|
||||||
|
));
|
||||||
|
BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error);
|
||||||
|
}
|
||||||
30
tests/test_expect.cpp
Normal file
30
tests/test_expect.cpp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_expect"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_expect)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
const auto v1_or_0 = toml::expect<int>(v1).unwrap_or(0);
|
||||||
|
const auto v2_or_0 = toml::expect<int>(v2).unwrap_or(0);
|
||||||
|
BOOST_TEST(42 == v1_or_0);
|
||||||
|
BOOST_TEST( 0 == v2_or_0);
|
||||||
|
|
||||||
|
const auto v1_or_none = toml::expect<int>(v1).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none"));
|
||||||
|
const auto v2_or_none = toml::expect<int>(v2).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none"));
|
||||||
|
BOOST_TEST("42" == v1_or_none);
|
||||||
|
BOOST_TEST("none" == v2_or_none);
|
||||||
|
}
|
||||||
|
}
|
||||||
292
tests/test_extended_conversions.cpp
Normal file
292
tests/test_extended_conversions.cpp
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_extended_conversions"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace extlib
|
||||||
|
{
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
std::string b;
|
||||||
|
};
|
||||||
|
struct bar
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
std::string b;
|
||||||
|
|
||||||
|
void from_toml(const toml::value& v)
|
||||||
|
{
|
||||||
|
this->a = toml::find<int>(v, "a");
|
||||||
|
this->b = toml::find<std::string>(v, "b");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::table into_toml() const
|
||||||
|
{
|
||||||
|
return toml::table{{"a", this->a}, {"b", this->b}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // extlib
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct from<extlib::foo>
|
||||||
|
{
|
||||||
|
static extlib::foo from_toml(const toml::value& v)
|
||||||
|
{
|
||||||
|
return extlib::foo{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct into<extlib::foo>
|
||||||
|
{
|
||||||
|
static toml::table into_toml(const extlib::foo& f)
|
||||||
|
{
|
||||||
|
return toml::table{{"a", f.a}, {"b", f.b}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // toml
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace extlib2
|
||||||
|
{
|
||||||
|
struct foo
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
std::string b;
|
||||||
|
};
|
||||||
|
struct bar
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
std::string b;
|
||||||
|
|
||||||
|
template<typename C, template<typename ...> class M, template<typename ...> class A>
|
||||||
|
void from_toml(const toml::basic_value<C, M, A>& v)
|
||||||
|
{
|
||||||
|
this->a = toml::find<int>(v, "a");
|
||||||
|
this->b = toml::find<std::string>(v, "b");
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
toml::table into_toml() const
|
||||||
|
{
|
||||||
|
return toml::table{{"a", this->a}, {"b", this->b}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // extlib2
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct from<extlib2::foo>
|
||||||
|
{
|
||||||
|
template<typename C, template<typename ...> class M, template<typename ...> class A>
|
||||||
|
static extlib2::foo from_toml(const toml::basic_value<C, M, A>& v)
|
||||||
|
{
|
||||||
|
return extlib2::foo{toml::find<int>(v, "a"), toml::find<std::string>(v, "b")};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct into<extlib2::foo>
|
||||||
|
{
|
||||||
|
static toml::table into_toml(const extlib2::foo& f)
|
||||||
|
{
|
||||||
|
return toml::table{{"a", f.a}, {"b", f.b}};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // toml
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const toml::value v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto foo = toml::get<extlib::foo>(v);
|
||||||
|
BOOST_TEST(foo.a == 42);
|
||||||
|
BOOST_TEST(foo.b == "baz");
|
||||||
|
|
||||||
|
const toml::value v2(foo);
|
||||||
|
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const toml::value v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto foo = toml::get<extlib2::foo>(v);
|
||||||
|
BOOST_TEST(foo.a == 42);
|
||||||
|
BOOST_TEST(foo.b == "baz");
|
||||||
|
|
||||||
|
const toml::value v2(foo);
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const toml::basic_value<toml::discard_comments, std::map, std::deque>
|
||||||
|
v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto foo = toml::get<extlib2::foo>(v);
|
||||||
|
BOOST_TEST(foo.a == 42);
|
||||||
|
BOOST_TEST(foo.b == "baz");
|
||||||
|
|
||||||
|
const toml::basic_value<toml::discard_comments, std::map, std::deque>
|
||||||
|
v2(foo);
|
||||||
|
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_conversion_by_specialization)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const toml::value v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto bar = toml::get<extlib::bar>(v);
|
||||||
|
BOOST_TEST(bar.a == 42);
|
||||||
|
BOOST_TEST(bar.b == "baz");
|
||||||
|
|
||||||
|
const toml::value v2(bar);
|
||||||
|
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto bar = toml::get<extlib2::bar>(v);
|
||||||
|
BOOST_TEST(bar.a == 42);
|
||||||
|
BOOST_TEST(bar.b == "baz");
|
||||||
|
|
||||||
|
const toml::value v2(bar);
|
||||||
|
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::basic_value<toml::discard_comments, std::map, std::deque>
|
||||||
|
v{{"a", 42}, {"b", "baz"}};
|
||||||
|
|
||||||
|
const auto bar = toml::get<extlib2::bar>(v);
|
||||||
|
BOOST_TEST(bar.a == 42);
|
||||||
|
BOOST_TEST(bar.b == "baz");
|
||||||
|
|
||||||
|
const toml::basic_value<toml::discard_comments, std::map, std::deque>
|
||||||
|
v2(bar);
|
||||||
|
|
||||||
|
BOOST_TEST(v == v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_recursive_conversion)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const toml::value v{
|
||||||
|
toml::table{{"a", 42}, {"b", "baz"}},
|
||||||
|
toml::table{{"a", 43}, {"b", "qux"}},
|
||||||
|
toml::table{{"a", 44}, {"b", "quux"}},
|
||||||
|
toml::table{{"a", 45}, {"b", "foobar"}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto foos = toml::get<std::vector<extlib::foo>>(v);
|
||||||
|
BOOST_TEST(foos.size() == 4ul);
|
||||||
|
BOOST_TEST(foos.at(0).a == 42);
|
||||||
|
BOOST_TEST(foos.at(1).a == 43);
|
||||||
|
BOOST_TEST(foos.at(2).a == 44);
|
||||||
|
BOOST_TEST(foos.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(foos.at(0).b == "baz");
|
||||||
|
BOOST_TEST(foos.at(1).b == "qux");
|
||||||
|
BOOST_TEST(foos.at(2).b == "quux");
|
||||||
|
BOOST_TEST(foos.at(3).b == "foobar");
|
||||||
|
|
||||||
|
const auto bars = toml::get<std::vector<extlib::bar>>(v);
|
||||||
|
BOOST_TEST(bars.size() == 4ul);
|
||||||
|
BOOST_TEST(bars.at(0).a == 42);
|
||||||
|
BOOST_TEST(bars.at(1).a == 43);
|
||||||
|
BOOST_TEST(bars.at(2).a == 44);
|
||||||
|
BOOST_TEST(bars.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(bars.at(0).b == "baz");
|
||||||
|
BOOST_TEST(bars.at(1).b == "qux");
|
||||||
|
BOOST_TEST(bars.at(2).b == "quux");
|
||||||
|
BOOST_TEST(bars.at(3).b == "foobar");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v{
|
||||||
|
toml::table{{"a", 42}, {"b", "baz"}},
|
||||||
|
toml::table{{"a", 43}, {"b", "qux"}},
|
||||||
|
toml::table{{"a", 44}, {"b", "quux"}},
|
||||||
|
toml::table{{"a", 45}, {"b", "foobar"}},
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto foos = toml::get<std::vector<extlib2::foo>>(v);
|
||||||
|
BOOST_TEST(foos.size() == 4ul);
|
||||||
|
BOOST_TEST(foos.at(0).a == 42);
|
||||||
|
BOOST_TEST(foos.at(1).a == 43);
|
||||||
|
BOOST_TEST(foos.at(2).a == 44);
|
||||||
|
BOOST_TEST(foos.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(foos.at(0).b == "baz");
|
||||||
|
BOOST_TEST(foos.at(1).b == "qux");
|
||||||
|
BOOST_TEST(foos.at(2).b == "quux");
|
||||||
|
BOOST_TEST(foos.at(3).b == "foobar");
|
||||||
|
|
||||||
|
const auto bars = toml::get<std::vector<extlib2::bar>>(v);
|
||||||
|
BOOST_TEST(bars.size() == 4ul);
|
||||||
|
BOOST_TEST(bars.at(0).a == 42);
|
||||||
|
BOOST_TEST(bars.at(1).a == 43);
|
||||||
|
BOOST_TEST(bars.at(2).a == 44);
|
||||||
|
BOOST_TEST(bars.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(bars.at(0).b == "baz");
|
||||||
|
BOOST_TEST(bars.at(1).b == "qux");
|
||||||
|
BOOST_TEST(bars.at(2).b == "quux");
|
||||||
|
BOOST_TEST(bars.at(3).b == "foobar");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const toml::basic_value<toml::discard_comments, std::map, std::deque>
|
||||||
|
v{
|
||||||
|
toml::table{{"a", 42}, {"b", "baz"}},
|
||||||
|
toml::table{{"a", 43}, {"b", "qux"}},
|
||||||
|
toml::table{{"a", 44}, {"b", "quux"}},
|
||||||
|
toml::table{{"a", 45}, {"b", "foobar"}}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto foos = toml::get<std::vector<extlib2::foo>>(v);
|
||||||
|
BOOST_TEST(foos.size() == 4ul);
|
||||||
|
BOOST_TEST(foos.at(0).a == 42);
|
||||||
|
BOOST_TEST(foos.at(1).a == 43);
|
||||||
|
BOOST_TEST(foos.at(2).a == 44);
|
||||||
|
BOOST_TEST(foos.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(foos.at(0).b == "baz");
|
||||||
|
BOOST_TEST(foos.at(1).b == "qux");
|
||||||
|
BOOST_TEST(foos.at(2).b == "quux");
|
||||||
|
BOOST_TEST(foos.at(3).b == "foobar");
|
||||||
|
|
||||||
|
const auto bars = toml::get<std::vector<extlib2::bar>>(v);
|
||||||
|
BOOST_TEST(bars.size() == 4ul);
|
||||||
|
BOOST_TEST(bars.at(0).a == 42);
|
||||||
|
BOOST_TEST(bars.at(1).a == 43);
|
||||||
|
BOOST_TEST(bars.at(2).a == 44);
|
||||||
|
BOOST_TEST(bars.at(3).a == 45);
|
||||||
|
|
||||||
|
BOOST_TEST(bars.at(0).b == "baz");
|
||||||
|
BOOST_TEST(bars.at(1).b == "qux");
|
||||||
|
BOOST_TEST(bars.at(2).b == "quux");
|
||||||
|
BOOST_TEST(bars.at(3).b == "foobar");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
432
tests/test_find.cpp
Normal file
432
tests/test_find.cpp
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_find"
|
||||||
|
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <array>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
using test_value_types = std::tuple<
|
||||||
|
toml::value,
|
||||||
|
toml::basic_value<toml::preserve_comments>,
|
||||||
|
toml::basic_value<toml::discard_comments, std::map, std::deque>,
|
||||||
|
toml::basic_value<toml::preserve_comments, std::map, std::deque>
|
||||||
|
>;
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_find_throws)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// value is not a table
|
||||||
|
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
|
||||||
|
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
|
||||||
|
toml::value v{{"key", 42}};
|
||||||
|
BOOST_CHECK_THROW(toml::find<toml::integer>(v, "different_key"),
|
||||||
|
std::out_of_range);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// the positive control.
|
||||||
|
toml::value v{{"key", 42}};
|
||||||
|
BOOST_TEST(42 == toml::find<int>(v, "key"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_find_recursive)
|
||||||
|
{
|
||||||
|
// recursively search tables
|
||||||
|
{
|
||||||
|
toml::value v{
|
||||||
|
{"a", {
|
||||||
|
{"b", {
|
||||||
|
{"c", {
|
||||||
|
{"d", 42}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
};
|
||||||
|
BOOST_TEST(42 == toml::find<int>(v, "a", "b", "c", "d"));
|
||||||
|
|
||||||
|
// reference that can be used to modify the content
|
||||||
|
auto& num = toml::find<toml::integer>(v, "a", "b", "c", "d");
|
||||||
|
num = 54;
|
||||||
|
BOOST_TEST(54 == toml::find<int>(v, "a", "b", "c", "d"));
|
||||||
|
|
||||||
|
const std::string a("a"), b("b"), c("c"), d("d");
|
||||||
|
auto& num2 = toml::find<toml::integer>(v, a, b, c, d);
|
||||||
|
num2 = 42;
|
||||||
|
BOOST_TEST(42 == toml::find<int>(v, a, b, c, d));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
value_type v{{"key", true}};
|
||||||
|
BOOST_TEST(true == toml::find<toml::boolean>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::boolean>(v, "key") = false;
|
||||||
|
BOOST_TEST(false == toml::find<toml::boolean>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", 42}};
|
||||||
|
BOOST_TEST(toml::integer(42) == toml::find<toml::integer>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::integer>(v, "key") = 54;
|
||||||
|
BOOST_TEST(toml::integer(54) == toml::find<toml::integer>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", 3.14}};
|
||||||
|
BOOST_TEST(toml::floating(3.14) == toml::find<toml::floating>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::floating>(v, "key") = 2.71;
|
||||||
|
BOOST_TEST(toml::floating(2.71) == toml::find<toml::floating>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", "foo"}};
|
||||||
|
BOOST_TEST(toml::string("foo", toml::string_t::basic) ==
|
||||||
|
toml::find<toml::string>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::string>(v, "key").str += "bar";
|
||||||
|
BOOST_TEST(toml::string("foobar", toml::string_t::basic) ==
|
||||||
|
toml::find<toml::string>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", value_type("foo", toml::string_t::literal)}};
|
||||||
|
BOOST_TEST(toml::string("foo", toml::string_t::literal) ==
|
||||||
|
toml::find<toml::string>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::string>(v, "key").str += "bar";
|
||||||
|
BOOST_TEST(toml::string("foobar", toml::string_t::literal) ==
|
||||||
|
toml::find<toml::string>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
toml::local_date d(2018, toml::month_t::Apr, 22);
|
||||||
|
value_type v{{"key", d}};
|
||||||
|
BOOST_CHECK(d == toml::find<toml::local_date>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::local_date>(v, "key").year = 2017;
|
||||||
|
d.year = 2017;
|
||||||
|
BOOST_CHECK(d == toml::find<toml::local_date>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
toml::local_time t(12, 30, 45);
|
||||||
|
value_type v{{"key", t}};
|
||||||
|
BOOST_CHECK(t == toml::find<toml::local_time>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::local_time>(v, "key").hour = 9;
|
||||||
|
t.hour = 9;
|
||||||
|
BOOST_CHECK(t == toml::find<toml::local_time>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22),
|
||||||
|
toml::local_time(12, 30, 45));
|
||||||
|
value_type v{{"key", dt}};
|
||||||
|
BOOST_CHECK(dt == toml::find<toml::local_datetime>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::local_datetime>(v, "key").date.year = 2017;
|
||||||
|
dt.date.year = 2017;
|
||||||
|
BOOST_CHECK(dt == toml::find<toml::local_datetime>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
toml::offset_datetime dt(toml::local_datetime(
|
||||||
|
toml::local_date(2018, toml::month_t::Apr, 22),
|
||||||
|
toml::local_time(12, 30, 45)), toml::time_offset(9, 0));
|
||||||
|
value_type v{{"key", dt}};
|
||||||
|
BOOST_CHECK(dt == toml::find<toml::offset_datetime>(v, "key"));
|
||||||
|
|
||||||
|
toml::find<toml::offset_datetime>(v, "key").date.year = 2017;
|
||||||
|
dt.date.year = 2017;
|
||||||
|
BOOST_CHECK(dt == toml::find<toml::offset_datetime>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typename value_type::array_type vec;
|
||||||
|
vec.push_back(value_type(42));
|
||||||
|
vec.push_back(value_type(54));
|
||||||
|
value_type v{{"key", vec}};
|
||||||
|
|
||||||
|
const bool result1 = (vec == toml::find<typename value_type::array_type>(v, "key"));
|
||||||
|
BOOST_CHECK(result1);
|
||||||
|
|
||||||
|
toml::find<typename value_type::array_type>(v, "key").push_back(value_type(123));
|
||||||
|
vec.push_back(value_type(123));
|
||||||
|
|
||||||
|
const bool result2 = (vec == toml::find<typename value_type::array_type>(v, "key"));
|
||||||
|
BOOST_CHECK(result2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typename value_type::table_type tab;
|
||||||
|
tab["key1"] = value_type(42);
|
||||||
|
tab["key2"] = value_type(3.14);
|
||||||
|
value_type v{{"key", tab}};
|
||||||
|
const bool result1 = (tab == toml::find<typename value_type::table_type>(v, "key"));
|
||||||
|
BOOST_CHECK(result1);
|
||||||
|
|
||||||
|
toml::find<typename value_type::table_type>(v, "key")["key3"] = value_type(123);
|
||||||
|
tab["key3"] = value_type(123);
|
||||||
|
const bool result2 = (tab == toml::find<typename value_type::table_type>(v, "key"));
|
||||||
|
BOOST_CHECK(result2);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v1(42);
|
||||||
|
value_type v{{"key", v1}};
|
||||||
|
BOOST_CHECK(v1 == toml::find(v, "key"));
|
||||||
|
|
||||||
|
value_type v2(54);
|
||||||
|
toml::find(v, "key") = v2;
|
||||||
|
BOOST_CHECK(v2 == toml::find(v, "key"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_integer_type, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
value_type v{{"key", 42}};
|
||||||
|
BOOST_TEST(int(42) == toml::find<int >(v, "key"));
|
||||||
|
BOOST_TEST(short(42) == toml::find<short >(v, "key"));
|
||||||
|
BOOST_TEST(char(42) == toml::find<char >(v, "key"));
|
||||||
|
BOOST_TEST(unsigned(42) == toml::find<unsigned >(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::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::uint16_t(42) == toml::find<std::uint16_t>(v, "key"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
value_type v{{"key", 3.14}};
|
||||||
|
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<long double>(3.14) == toml::find<long double>(v, "key"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
value_type v{{"key", toml::string("foo", toml::string_t::basic)}};
|
||||||
|
BOOST_TEST("foo" == toml::find<std::string>(v, "key"));
|
||||||
|
toml::find<std::string>(v, "key") += "bar";
|
||||||
|
BOOST_TEST("foobar" == toml::find<std::string>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", toml::string("foo", toml::string_t::literal)}};
|
||||||
|
BOOST_TEST("foo" == toml::find<std::string>(v, "key"));
|
||||||
|
toml::find<std::string>(v, "key") += "bar";
|
||||||
|
BOOST_TEST("foobar" == toml::find<std::string>(v, "key"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
{
|
||||||
|
value_type v{{"key", toml::string("foo", toml::string_t::basic)}};
|
||||||
|
BOOST_TEST("foo" == toml::find<std::string_view>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v{{"key", toml::string("foo", toml::string_t::literal)}};
|
||||||
|
BOOST_TEST("foo" == toml::find<std::string_view>(v, "key"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
value_type v{{"key", {42, 54, 69, 72}}};
|
||||||
|
|
||||||
|
const std::vector<int> vec = toml::find<std::vector<int>>(v, "key");
|
||||||
|
const std::list<short> lst = toml::find<std::list<short>>(v, "key");
|
||||||
|
const std::deque<std::int64_t> deq = toml::find<std::deque<std::int64_t>>(v, "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>>(v, "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>>(v, "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> >(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)
|
||||||
|
{
|
||||||
|
value_type v1{42, 54, 69, 72};
|
||||||
|
value_type v2{"foo", "bar", "baz"};
|
||||||
|
value_type v{{"key", {v1, v2}}};
|
||||||
|
|
||||||
|
std::pair<std::vector<int>, std::vector<std::string>> p =
|
||||||
|
toml::find<std::pair<std::vector<int>, std::vector<std::string>>>(v, "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>>>(v, "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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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>(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)
|
||||||
|
{
|
||||||
|
value_type v1{{"key", toml::local_time{12, 30, 45}}};
|
||||||
|
const auto time = toml::find<std::chrono::seconds>(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)
|
||||||
|
{
|
||||||
|
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>(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)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
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{9, 0})}};
|
||||||
|
// 2018-04-01T12:30:00+09:00
|
||||||
|
// == 2018-04-01T03:30:00Z
|
||||||
|
|
||||||
|
const auto date = toml::find<std::chrono::system_clock::time_point>(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 == 3);
|
||||||
|
BOOST_TEST(tm.tm_min == 30);
|
||||||
|
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>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
360
tests/test_find_or.cpp
Normal file
360
tests/test_find_or.cpp
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_find_or"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using test_value_types = std::tuple<
|
||||||
|
toml::value,
|
||||||
|
toml::basic_value<toml::preserve_comments>,
|
||||||
|
toml::basic_value<toml::discard_comments, std::map, std::deque>,
|
||||||
|
toml::basic_value<toml::preserve_comments, std::map, std::deque>
|
||||||
|
>;
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::vector<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::deque<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::list<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits,
|
||||||
|
typename Key, typename Value, typename Comp, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
|
const std::map<Key, Value, Comp, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits,
|
||||||
|
typename Key, typename Value, typename Hash, typename Eq, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
|
const std::unordered_map<Key, Value, Hash, Eq, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} // test
|
||||||
|
|
||||||
|
#define TOML11_TEST_FIND_OR_EXACT(toml_type, init_expr, opt_expr)\
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
const toml::toml_type init init_expr ; \
|
||||||
|
const toml::toml_type opt opt_expr ; \
|
||||||
|
const value_type v{{"key", init}}; \
|
||||||
|
BOOST_TEST(init != opt); \
|
||||||
|
BOOST_TEST(init == toml::find_or(v, "key", opt)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_exact, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(boolean, ( true), (false))
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(integer, ( 42), ( 54))
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(floating, ( 3.14), ( 2.71))
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(string, ("foo"), ("bar"))
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30))
|
||||||
|
TOML11_TEST_FIND_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1),
|
||||||
|
(1999, toml::month_t::Jan, 2))
|
||||||
|
TOML11_TEST_FIND_OR_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_FIND_OR_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};
|
||||||
|
const typename value_type::array_type opt {6,7,8,9,10};
|
||||||
|
const value_type v{{"key", init}};
|
||||||
|
BOOST_TEST(init != opt);
|
||||||
|
BOOST_TEST(init == toml::find_or(v, "key", opt));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}};
|
||||||
|
const value_type v{{"key", init}};
|
||||||
|
BOOST_TEST(init != opt);
|
||||||
|
BOOST_TEST(init == toml::find_or(v, "key", opt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_FIND_OR_EXACT
|
||||||
|
|
||||||
|
#define TOML11_TEST_FIND_OR_MODIFY(toml_type, init_expr, opt_expr)\
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
const toml::toml_type init init_expr ; \
|
||||||
|
toml::toml_type opt1 opt_expr ; \
|
||||||
|
toml::toml_type opt2 opt_expr ; \
|
||||||
|
value_type v{{"key", init}}; \
|
||||||
|
BOOST_TEST(init != opt1); \
|
||||||
|
toml::find_or(v, "key", opt2) = opt1; \
|
||||||
|
BOOST_TEST(opt1 == toml::find<toml::toml_type>(v, "key"));\
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_modify, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(boolean, ( true), (false))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(integer, ( 42), ( 54))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(floating, ( 3.14), ( 2.71))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(string, ("foo"), ("bar"))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1),
|
||||||
|
(1999, toml::month_t::Jan, 2))
|
||||||
|
TOML11_TEST_FIND_OR_MODIFY(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_MODIFY(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 opt1{6,7,8,9,10};
|
||||||
|
typename value_type::array_type opt2{6,7,8,9,10};
|
||||||
|
BOOST_TEST(init != opt1);
|
||||||
|
value_type v{{"key", init}};
|
||||||
|
toml::find_or(v, "key", opt2) = opt1;
|
||||||
|
BOOST_TEST(opt1 == toml::find<typename value_type::array_type>(v, "key"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}};
|
||||||
|
typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}};
|
||||||
|
value_type v{{"key", init}};
|
||||||
|
BOOST_TEST(init != opt1);
|
||||||
|
toml::find_or(v, "key", opt2) = opt1;
|
||||||
|
BOOST_TEST(opt1 == toml::find<typename value_type::table_type>(v, "key"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_FIND_OR_MODIFY
|
||||||
|
|
||||||
|
#define TOML11_TEST_FIND_OR_FALLBACK(init_type, opt_type) \
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
value_type v(init_type); \
|
||||||
|
BOOST_TEST(opt_type == toml::find_or(v, "key", opt_type));\
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_or_fallback, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
const toml::boolean boolean (true);
|
||||||
|
const toml::integer integer (42);
|
||||||
|
const toml::floating floating (3.14);
|
||||||
|
const toml::string string ("foo");
|
||||||
|
const toml::local_time local_time (12, 30, 45);
|
||||||
|
const toml::local_date local_date (2019, toml::month_t::Apr, 1);
|
||||||
|
const toml::local_datetime local_datetime (
|
||||||
|
toml::local_date(2019, toml::month_t::Apr, 1),
|
||||||
|
toml::local_time(12, 30, 45));
|
||||||
|
const toml::offset_datetime offset_datetime(
|
||||||
|
toml::local_date(2019, toml::month_t::Apr, 1),
|
||||||
|
toml::local_time(12, 30, 45), toml::time_offset( 9, 0));
|
||||||
|
|
||||||
|
using array_type = typename value_type::array_type;
|
||||||
|
using table_type = typename value_type::table_type;
|
||||||
|
const array_type array{1, 2, 3, 4, 5};
|
||||||
|
const table_type table{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(boolean, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(integer, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(floating, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(string, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_time, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_date, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(local_datetime, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, array );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(offset_datetime, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(array, table );
|
||||||
|
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, boolean );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, integer );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, floating );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, string );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, local_time );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, local_date );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, local_datetime );
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, offset_datetime);
|
||||||
|
TOML11_TEST_FIND_OR_FALLBACK(table, array );
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_FIND_OR_FALLBACK
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_find_or_integer)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v = toml::table{{"num", 42}};
|
||||||
|
BOOST_TEST(42u == toml::find_or(v, "num", 0u));
|
||||||
|
BOOST_TEST(0u == toml::find_or(v, "foo", 0u));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_find_or_floating)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1{{"key", 42}};
|
||||||
|
toml::value v2{{"key", 3.14}};
|
||||||
|
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_AUTO_TEST_CASE(test_find_or_string)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1 = toml::table{{"key", "foobar"}};
|
||||||
|
toml::value v2 = toml::table{{"key", 42}};
|
||||||
|
|
||||||
|
std::string s1("bazqux");
|
||||||
|
const std::string s2("bazqux");
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::find_or(v1, "key", s1));
|
||||||
|
BOOST_TEST("bazqux" == toml::find_or(v2, "key", s1));
|
||||||
|
|
||||||
|
std::string& v1r = toml::find_or(v1, "key", s1);
|
||||||
|
std::string& s1r = toml::find_or(v2, "key", s1);
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == v1r);
|
||||||
|
BOOST_TEST("bazqux" == s1r);
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::find_or(v1, "key", s2));
|
||||||
|
BOOST_TEST("bazqux" == toml::find_or(v2, "key", s2));
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::find_or(std::move(v1), "key", std::move(s1)));
|
||||||
|
s1 = "bazqux"; // restoring moved value
|
||||||
|
BOOST_TEST("bazqux" == toml::find_or(std::move(v2), "key", std::move(s1)));
|
||||||
|
}
|
||||||
|
// string literal
|
||||||
|
{
|
||||||
|
toml::value v1 = toml::table{{"key", "foobar"}};
|
||||||
|
toml::value v2 = toml::table{{"key",42}};
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::find_or(v1, "key", "bazqux"));
|
||||||
|
BOOST_TEST("bazqux" == toml::find_or(v2, "key", "bazqux"));
|
||||||
|
|
||||||
|
const char* lit = "bazqux";
|
||||||
|
BOOST_TEST("foobar" == toml::find_or(v1, "key", lit));
|
||||||
|
BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit));
|
||||||
|
}
|
||||||
|
}
|
||||||
75
tests/test_format_error.cpp
Normal file
75
tests/test_format_error.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_format_error"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
|
||||||
|
// to check it successfully compiles. it does not check the formatted string.
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_1_value)
|
||||||
|
{
|
||||||
|
toml::value val(42);
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error", val, "this is a value");
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error", val, "this is a value",
|
||||||
|
{"this is a hint"});
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_2_values)
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error with two values",
|
||||||
|
v1, "this is the answer",
|
||||||
|
v2, "this is the pi");
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error with two values",
|
||||||
|
v1, "this is the answer",
|
||||||
|
v2, "this is the pi",
|
||||||
|
{"hint"});
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_3_values)
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
toml::value v3("foo");
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error with two values",
|
||||||
|
v1, "this is the answer",
|
||||||
|
v2, "this is the pi",
|
||||||
|
v3, "this is a meta-syntactic variable");
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string pretty_error =
|
||||||
|
toml::format_error("[error] test error with two values",
|
||||||
|
v1, "this is the answer",
|
||||||
|
v2, "this is the pi",
|
||||||
|
v3, "this is a meta-syntactic variable",
|
||||||
|
{"hint 1", "hint 2"});
|
||||||
|
std::cout << pretty_error << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#define BOOST_TEST_MODULE "test_from_toml"
|
|
||||||
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_TEST_NO_LIB
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
#endif
|
|
||||||
#include <toml.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_from_toml)
|
|
||||||
{
|
|
||||||
toml::boolean b = false;
|
|
||||||
toml::integer i = 0;
|
|
||||||
toml::floating f = 0.;
|
|
||||||
toml::string s;
|
|
||||||
toml::local_date dt;
|
|
||||||
toml::array a;
|
|
||||||
toml::table t;
|
|
||||||
{
|
|
||||||
toml::value v(true);
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK_EQUAL(b, true);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v(42);
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK_EQUAL(i, 42);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v(3.14);
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK_EQUAL(f, 3.14);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v("foo");
|
|
||||||
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK_EQUAL(s, "foo");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v(toml::local_date(2018, toml::month_t::Apr, 22));
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK(dt == toml::local_date(2018, toml::month_t::Apr, 22));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::array ref{toml::value(42), toml::value(54)};
|
|
||||||
toml::value v(ref);
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK(ref == a);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::table ref{{"key1", 42}, {"key2", 3.14}};
|
|
||||||
toml::value v(ref);
|
|
||||||
toml::from_toml(std::tie(b, i, f, s, dt, a, t), v);
|
|
||||||
BOOST_CHECK(ref == t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -5,272 +5,284 @@
|
|||||||
#define BOOST_TEST_NO_LIB
|
#define BOOST_TEST_NO_LIB
|
||||||
#include <boost/test/included/unit_test.hpp>
|
#include <boost/test/included/unit_test.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include <toml/value.hpp>
|
#include <toml.hpp>
|
||||||
#include <toml/get.hpp>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using test_value_types = std::tuple<
|
||||||
|
toml::value,
|
||||||
|
toml::basic_value<toml::preserve_comments>,
|
||||||
|
toml::basic_value<toml::discard_comments, std::map, std::deque>,
|
||||||
|
toml::basic_value<toml::preserve_comments, std::map, std::deque>
|
||||||
|
>;
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_exact)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
toml::value v(true);
|
value_type v(true);
|
||||||
BOOST_CHECK_EQUAL(true, toml::get<toml::boolean>(v));
|
BOOST_TEST(true == toml::get<toml::boolean>(v));
|
||||||
|
|
||||||
toml::get<toml::boolean>(v) = false;
|
toml::get<toml::boolean>(v) = false;
|
||||||
BOOST_CHECK_EQUAL(false, toml::get<toml::boolean>(v));
|
BOOST_TEST(false == toml::get<toml::boolean>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::value v(42);
|
value_type v(42);
|
||||||
BOOST_CHECK_EQUAL(toml::integer(42), toml::get<toml::integer>(v));
|
BOOST_TEST(toml::integer(42) == toml::get<toml::integer>(v));
|
||||||
|
|
||||||
toml::get<toml::integer>(v) = 54;
|
toml::get<toml::integer>(v) = 54;
|
||||||
BOOST_CHECK_EQUAL(toml::integer(54), toml::get<toml::integer>(v));
|
BOOST_TEST(toml::integer(54) == toml::get<toml::integer>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::value v(3.14);
|
value_type v(3.14);
|
||||||
BOOST_CHECK_EQUAL(toml::floating(3.14), toml::get<toml::floating>(v));
|
BOOST_TEST(toml::floating(3.14) == toml::get<toml::floating>(v));
|
||||||
|
|
||||||
toml::get<toml::floating>(v) = 2.71;
|
toml::get<toml::floating>(v) = 2.71;
|
||||||
BOOST_CHECK_EQUAL(toml::floating(2.71), toml::get<toml::floating>(v));
|
BOOST_TEST(toml::floating(2.71) == toml::get<toml::floating>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::value v("foo");
|
value_type v("foo");
|
||||||
BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::basic),
|
BOOST_TEST(toml::string("foo", toml::string_t::basic) ==
|
||||||
toml::get<toml::string>(v));
|
toml::get<toml::string>(v));
|
||||||
|
|
||||||
toml::get<toml::string>(v).str += "bar";
|
toml::get<toml::string>(v).str += "bar";
|
||||||
BOOST_CHECK_EQUAL(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::value v("foo", toml::string_t::literal);
|
value_type v("foo", toml::string_t::literal);
|
||||||
BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::literal),
|
BOOST_TEST(toml::string("foo", toml::string_t::literal) ==
|
||||||
toml::get<toml::string>(v));
|
toml::get<toml::string>(v));
|
||||||
|
|
||||||
toml::get<toml::string>(v).str += "bar";
|
toml::get<toml::string>(v).str += "bar";
|
||||||
BOOST_CHECK_EQUAL(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::local_date d(2018, toml::month_t::Apr, 22);
|
toml::local_date d(2018, toml::month_t::Apr, 22);
|
||||||
toml::value v(d);
|
value_type v(d);
|
||||||
BOOST_CHECK(d == toml::get<toml::local_date>(v));
|
BOOST_TEST(d == toml::get<toml::local_date>(v));
|
||||||
|
|
||||||
toml::get<toml::local_date>(v).year = 2017;
|
toml::get<toml::local_date>(v).year = 2017;
|
||||||
d.year = 2017;
|
d.year = 2017;
|
||||||
BOOST_CHECK(d == toml::get<toml::local_date>(v));
|
BOOST_TEST(d == toml::get<toml::local_date>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::local_time t(12, 30, 45);
|
toml::local_time t(12, 30, 45);
|
||||||
toml::value v(t);
|
value_type v(t);
|
||||||
BOOST_CHECK(t == toml::get<toml::local_time>(v));
|
BOOST_TEST(t == toml::get<toml::local_time>(v));
|
||||||
|
|
||||||
toml::get<toml::local_time>(v).hour = 9;
|
toml::get<toml::local_time>(v).hour = 9;
|
||||||
t.hour = 9;
|
t.hour = 9;
|
||||||
BOOST_CHECK(t == toml::get<toml::local_time>(v));
|
BOOST_TEST(t == toml::get<toml::local_time>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
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),
|
||||||
toml::local_time(12, 30, 45));
|
toml::local_time(12, 30, 45));
|
||||||
toml::value v(dt);
|
value_type v(dt);
|
||||||
BOOST_CHECK(dt == toml::get<toml::local_datetime>(v));
|
BOOST_TEST(dt == toml::get<toml::local_datetime>(v));
|
||||||
|
|
||||||
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_CHECK(dt == toml::get<toml::local_datetime>(v));
|
BOOST_TEST(dt == toml::get<toml::local_datetime>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::offset_datetime dt(toml::local_datetime(
|
toml::offset_datetime dt(toml::local_datetime(
|
||||||
toml::local_date(2018, toml::month_t::Apr, 22),
|
toml::local_date(2018, toml::month_t::Apr, 22),
|
||||||
toml::local_time(12, 30, 45)), toml::time_offset(9, 0));
|
toml::local_time(12, 30, 45)), toml::time_offset(9, 0));
|
||||||
toml::value v(dt);
|
value_type v(dt);
|
||||||
BOOST_CHECK(dt == toml::get<toml::offset_datetime>(v));
|
BOOST_TEST(dt == toml::get<toml::offset_datetime>(v));
|
||||||
|
|
||||||
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_CHECK(dt == toml::get<toml::offset_datetime>(v));
|
BOOST_TEST(dt == toml::get<toml::offset_datetime>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::array vec;
|
using array_type = typename value_type::array_type;
|
||||||
vec.push_back(toml::value(42));
|
array_type vec;
|
||||||
vec.push_back(toml::value(54));
|
vec.push_back(value_type(42));
|
||||||
toml::value v(vec);
|
vec.push_back(value_type(54));
|
||||||
BOOST_CHECK(vec == toml::get<toml::array>(v));
|
value_type v(vec);
|
||||||
|
BOOST_TEST(vec == toml::get<array_type>(v));
|
||||||
|
|
||||||
toml::get<toml::array>(v).push_back(toml::value(123));
|
toml::get<array_type>(v).push_back(value_type(123));
|
||||||
vec.push_back(toml::value(123));
|
vec.push_back(value_type(123));
|
||||||
BOOST_CHECK(vec == toml::get<toml::array>(v));
|
BOOST_TEST(vec == toml::get<array_type>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::table tab;
|
using table_type = typename value_type::table_type;
|
||||||
tab["key1"] = toml::value(42);
|
table_type tab;
|
||||||
tab["key2"] = toml::value(3.14);
|
tab["key1"] = value_type(42);
|
||||||
toml::value v(tab);
|
tab["key2"] = value_type(3.14);
|
||||||
BOOST_CHECK(tab == toml::get<toml::table>(v));
|
value_type v(tab);
|
||||||
|
BOOST_TEST(tab == toml::get<table_type>(v));
|
||||||
|
|
||||||
toml::get<toml::table>(v)["key3"] = toml::value(123);
|
toml::get<table_type>(v)["key3"] = value_type(123);
|
||||||
tab["key3"] = toml::value(123);
|
tab["key3"] = value_type(123);
|
||||||
BOOST_CHECK(tab == toml::get<toml::table>(v));
|
BOOST_TEST(tab == toml::get<table_type>(v));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v1(42);
|
||||||
|
BOOST_TEST(v1 == toml::get<value_type>(v1));
|
||||||
|
|
||||||
|
value_type v2(54);
|
||||||
|
toml::get<value_type>(v1) = v2;
|
||||||
|
BOOST_TEST(v2 == toml::get<value_type>(v1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_integer_type)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_integer_type, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
toml::value v(42);
|
value_type v(42);
|
||||||
BOOST_CHECK_EQUAL(int(42), toml::get<int >(v));
|
BOOST_TEST(int(42) == toml::get<int >(v));
|
||||||
BOOST_CHECK_EQUAL(short(42), toml::get<short >(v));
|
BOOST_TEST(short(42) == toml::get<short >(v));
|
||||||
BOOST_CHECK_EQUAL(char(42), toml::get<char >(v));
|
BOOST_TEST(char(42) == toml::get<char >(v));
|
||||||
BOOST_CHECK_EQUAL(unsigned(42), toml::get<unsigned >(v));
|
BOOST_TEST(unsigned(42) == toml::get<unsigned >(v));
|
||||||
BOOST_CHECK_EQUAL(long(42), toml::get<long >(v));
|
BOOST_TEST(long(42) == toml::get<long >(v));
|
||||||
BOOST_CHECK_EQUAL(std::int64_t(42), toml::get<std::int64_t >(v));
|
BOOST_TEST(std::int64_t(42) == toml::get<std::int64_t >(v));
|
||||||
BOOST_CHECK_EQUAL(std::uint64_t(42), toml::get<std::uint64_t>(v));
|
BOOST_TEST(std::uint64_t(42) == toml::get<std::uint64_t>(v));
|
||||||
BOOST_CHECK_EQUAL(std::int16_t(42), toml::get<std::int16_t >(v));
|
BOOST_TEST(std::int16_t(42) == toml::get<std::int16_t >(v));
|
||||||
BOOST_CHECK_EQUAL(std::uint16_t(42), toml::get<std::uint16_t>(v));
|
BOOST_TEST(std::uint16_t(42) == toml::get<std::uint16_t>(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_floating_type)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_floating_type, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
toml::value v(3.14);
|
value_type v(3.14);
|
||||||
BOOST_CHECK_EQUAL(static_cast<float >(3.14), toml::get<float >(v));
|
BOOST_TEST(static_cast<float >(3.14) == toml::get<float >(v));
|
||||||
BOOST_CHECK_EQUAL(static_cast<double >(3.14), toml::get<double >(v));
|
BOOST_TEST(static_cast<double >(3.14) == toml::get<double >(v));
|
||||||
BOOST_CHECK_EQUAL(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_AUTO_TEST_CASE(test_get_string_type)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_string_type, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
toml::value v("foo", toml::string_t::basic);
|
value_type v("foo", toml::string_t::basic);
|
||||||
BOOST_CHECK_EQUAL("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_CHECK_EQUAL("foobar", toml::get<std::string>(v));
|
BOOST_TEST("foobar" == toml::get<std::string>(v));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::value v("foo", toml::string_t::literal);
|
value_type v("foo", toml::string_t::literal);
|
||||||
BOOST_CHECK_EQUAL("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_CHECK_EQUAL("foobar", toml::get<std::string>(v));
|
BOOST_TEST("foobar" == toml::get<std::string>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
{
|
||||||
|
value_type v("foo", toml::string_t::basic);
|
||||||
|
BOOST_TEST("foo" == toml::get<std::string_view>(v));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value_type v("foo", toml::string_t::literal);
|
||||||
|
BOOST_TEST("foo" == toml::get<std::string_view>(v));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_array)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
toml::value v(toml::array(0));
|
const value_type v{42, 54, 69, 72};
|
||||||
toml::get<toml::array>(v).push_back(toml::value(42));
|
|
||||||
toml::get<toml::array>(v).push_back(toml::value(54));
|
|
||||||
toml::get<toml::array>(v).push_back(toml::value(69));
|
|
||||||
toml::get<toml::array>(v).push_back(toml::value(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_CHECK_EQUAL(42, vec.at(0));
|
BOOST_TEST(42 == vec.at(0));
|
||||||
BOOST_CHECK_EQUAL(54, vec.at(1));
|
BOOST_TEST(54 == vec.at(1));
|
||||||
BOOST_CHECK_EQUAL(69, vec.at(2));
|
BOOST_TEST(69 == vec.at(2));
|
||||||
BOOST_CHECK_EQUAL(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_CHECK_EQUAL(static_cast<short>(42), *(iter++));
|
BOOST_TEST(static_cast<short>(42) == *(iter++));
|
||||||
BOOST_CHECK_EQUAL(static_cast<short>(54), *(iter++));
|
BOOST_TEST(static_cast<short>(54) == *(iter++));
|
||||||
BOOST_CHECK_EQUAL(static_cast<short>(69), *(iter++));
|
BOOST_TEST(static_cast<short>(69) == *(iter++));
|
||||||
BOOST_CHECK_EQUAL(static_cast<short>(72), *(iter++));
|
BOOST_TEST(static_cast<short>(72) == *(iter++));
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(static_cast<std::int64_t>(42), deq.at(0));
|
BOOST_TEST(static_cast<std::int64_t>(42) == deq.at(0));
|
||||||
BOOST_CHECK_EQUAL(static_cast<std::int64_t>(54), deq.at(1));
|
BOOST_TEST(static_cast<std::int64_t>(54) == deq.at(1));
|
||||||
BOOST_CHECK_EQUAL(static_cast<std::int64_t>(69), deq.at(2));
|
BOOST_TEST(static_cast<std::int64_t>(69) == deq.at(2));
|
||||||
BOOST_CHECK_EQUAL(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_CHECK_EQUAL(static_cast<int>(42), ary.at(0));
|
BOOST_TEST(static_cast<int>(42) == ary.at(0));
|
||||||
BOOST_CHECK_EQUAL(static_cast<int>(54), ary.at(1));
|
BOOST_TEST(static_cast<int>(54) == ary.at(1));
|
||||||
BOOST_CHECK_EQUAL(static_cast<int>(69), ary.at(2));
|
BOOST_TEST(static_cast<int>(69) == ary.at(2));
|
||||||
BOOST_CHECK_EQUAL(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_CHECK_EQUAL(static_cast<int >(42), std::get<0>(tpl));
|
BOOST_TEST(static_cast<int >(42) == std::get<0>(tpl));
|
||||||
BOOST_CHECK_EQUAL(static_cast<short >(54), std::get<1>(tpl));
|
BOOST_TEST(static_cast<short >(54) == std::get<1>(tpl));
|
||||||
BOOST_CHECK_EQUAL(static_cast<unsigned>(69), std::get<2>(tpl));
|
BOOST_TEST(static_cast<unsigned>(69) == std::get<2>(tpl));
|
||||||
BOOST_CHECK_EQUAL(static_cast<long >(72), std::get<3>(tpl));
|
BOOST_TEST(static_cast<long >(72) == std::get<3>(tpl));
|
||||||
|
|
||||||
toml::value p(toml::array{});
|
const value_type p{3.14, 2.71};
|
||||||
toml::get<toml::array>(p).push_back(toml::value(3.14));
|
|
||||||
toml::get<toml::array>(p).push_back(toml::value(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_CHECK_EQUAL(3.14, pr.first);
|
BOOST_TEST(3.14 == pr.first);
|
||||||
BOOST_CHECK_EQUAL(2.71, pr.second);
|
BOOST_TEST(2.71 == pr.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_array_of_array)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_array_of_array, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
toml::value v1(toml::array{});
|
const value_type v1{42, 54, 69, 72};
|
||||||
toml::get<toml::array>(v1).push_back(toml::value(42));
|
const value_type v2{"foo", "bar", "baz"};
|
||||||
toml::get<toml::array>(v1).push_back(toml::value(54));
|
const value_type v{v1, v2};
|
||||||
toml::get<toml::array>(v1).push_back(toml::value(69));
|
|
||||||
toml::get<toml::array>(v1).push_back(toml::value(72));
|
|
||||||
|
|
||||||
toml::value v2(toml::array{});
|
|
||||||
toml::get<toml::array>(v2).push_back(toml::value("foo"));
|
|
||||||
toml::get<toml::array>(v2).push_back(toml::value("bar"));
|
|
||||||
toml::get<toml::array>(v2).push_back(toml::value("baz"));
|
|
||||||
|
|
||||||
toml::value v(toml::array(2));
|
|
||||||
toml::get<toml::array>(v).at(0) = v1;
|
|
||||||
toml::get<toml::array>(v).at(1) = 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_CHECK_EQUAL(p.first.at(0), 42);
|
BOOST_TEST(p.first.at(0) == 42);
|
||||||
BOOST_CHECK_EQUAL(p.first.at(1), 54);
|
BOOST_TEST(p.first.at(1) == 54);
|
||||||
BOOST_CHECK_EQUAL(p.first.at(2), 69);
|
BOOST_TEST(p.first.at(2) == 69);
|
||||||
BOOST_CHECK_EQUAL(p.first.at(3), 72);
|
BOOST_TEST(p.first.at(3) == 72);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(p.second.at(0), "foo");
|
BOOST_TEST(p.second.at(0) == "foo");
|
||||||
BOOST_CHECK_EQUAL(p.second.at(1), "bar");
|
BOOST_TEST(p.second.at(1) == "bar");
|
||||||
BOOST_CHECK_EQUAL(p.second.at(2), "baz");
|
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_CHECK_EQUAL(std::get<0>(t).at(0), 42);
|
BOOST_TEST(std::get<0>(t).at(0) == 42);
|
||||||
BOOST_CHECK_EQUAL(std::get<0>(t).at(1), 54);
|
BOOST_TEST(std::get<0>(t).at(1) == 54);
|
||||||
BOOST_CHECK_EQUAL(std::get<0>(t).at(2), 69);
|
BOOST_TEST(std::get<0>(t).at(2) == 69);
|
||||||
BOOST_CHECK_EQUAL(std::get<0>(t).at(3), 72);
|
BOOST_TEST(std::get<0>(t).at(3) == 72);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(std::get<1>(t).at(0), "foo");
|
BOOST_TEST(std::get<1>(t).at(0) == "foo");
|
||||||
BOOST_CHECK_EQUAL(std::get<1>(t).at(1), "bar");
|
BOOST_TEST(std::get<1>(t).at(1) == "bar");
|
||||||
BOOST_CHECK_EQUAL(std::get<1>(t).at(2), "baz");
|
BOOST_TEST(std::get<1>(t).at(2) == "baz");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_table)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_table, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
toml::value v1(toml::table{
|
const value_type v1{
|
||||||
{"key1", 1},
|
{"key1", 1},
|
||||||
{"key2", 2},
|
{"key2", 2},
|
||||||
{"key3", 3},
|
{"key3", 3},
|
||||||
{"key4", 4}
|
{"key4", 4}
|
||||||
});
|
};
|
||||||
|
|
||||||
const auto v = toml::get<std::map<std::string, int>>(v1);
|
const auto v = toml::get<std::map<std::string, int>>(v1);
|
||||||
BOOST_CHECK_EQUAL(v.at("key1"), 1);
|
BOOST_TEST(v.at("key1") == 1);
|
||||||
BOOST_CHECK_EQUAL(v.at("key2"), 2);
|
BOOST_TEST(v.at("key2") == 2);
|
||||||
BOOST_CHECK_EQUAL(v.at("key3"), 3);
|
BOOST_TEST(v.at("key3") == 3);
|
||||||
BOOST_CHECK_EQUAL(v.at("key4"), 4);
|
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(test_get_toml_local_date)
|
|
||||||
{
|
{
|
||||||
toml::value v1(toml::local_date{2018, toml::month_t::Apr, 1});
|
value_type v1(toml::local_date{2018, toml::month_t::Apr, 1});
|
||||||
const auto date = std::chrono::system_clock::to_time_t(
|
const auto date = std::chrono::system_clock::to_time_t(
|
||||||
toml::get<std::chrono::system_clock::time_point>(v1));
|
toml::get<std::chrono::system_clock::time_point>(v1));
|
||||||
|
|
||||||
@@ -283,20 +295,22 @@ BOOST_AUTO_TEST_CASE(test_get_toml_local_date)
|
|||||||
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_CHECK_EQUAL(c, date);
|
BOOST_TEST(c == date);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_local_time)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_time, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
toml::value v1(toml::local_time{12, 30, 45});
|
value_type v1(toml::local_time{12, 30, 45});
|
||||||
const auto time = toml::get<std::chrono::seconds>(v1);
|
const auto time = toml::get<std::chrono::seconds>(v1);
|
||||||
BOOST_CHECK(time == std::chrono::hours(12) +
|
const bool result = time == std::chrono::hours(12) +
|
||||||
std::chrono::minutes(30) + std::chrono::seconds(45));
|
std::chrono::minutes(30) +
|
||||||
|
std::chrono::seconds(45);
|
||||||
|
BOOST_TEST(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_local_datetime)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_datetime, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
toml::value v1(toml::local_datetime(
|
value_type v1(toml::local_datetime(
|
||||||
toml::local_date{2018, toml::month_t::Apr, 1},
|
toml::local_date{2018, toml::month_t::Apr, 1},
|
||||||
toml::local_time{12, 30, 45}));
|
toml::local_time{12, 30, 45}));
|
||||||
|
|
||||||
@@ -311,13 +325,13 @@ BOOST_AUTO_TEST_CASE(test_get_toml_local_datetime)
|
|||||||
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_CHECK_EQUAL(c, date);
|
BOOST_TEST(c == date);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_toml_offset_datetime)
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
toml::value v1(toml::offset_datetime(
|
value_type v1(toml::offset_datetime(
|
||||||
toml::local_date{2018, toml::month_t::Apr, 1},
|
toml::local_date{2018, toml::month_t::Apr, 1},
|
||||||
toml::local_time{12, 30, 0},
|
toml::local_time{12, 30, 0},
|
||||||
toml::time_offset{9, 0}));
|
toml::time_offset{9, 0}));
|
||||||
@@ -329,18 +343,18 @@ BOOST_AUTO_TEST_CASE(test_get_toml_offset_datetime)
|
|||||||
|
|
||||||
// get time_t as gmtime (2018-04-01T03:30:00Z)
|
// get time_t as gmtime (2018-04-01T03:30:00Z)
|
||||||
const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe!
|
const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe!
|
||||||
BOOST_CHECK(tmp);
|
BOOST_TEST(tmp);
|
||||||
const auto tm = *tmp;
|
const auto tm = *tmp;
|
||||||
BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018);
|
BOOST_TEST(tm.tm_year + 1900 == 2018);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4);
|
BOOST_TEST(tm.tm_mon + 1 == 4);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_mday, 1);
|
BOOST_TEST(tm.tm_mday == 1);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_hour, 3);
|
BOOST_TEST(tm.tm_hour == 3);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_min, 30);
|
BOOST_TEST(tm.tm_min == 30);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_sec, 0);
|
BOOST_TEST(tm.tm_sec == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
toml::value v1(toml::offset_datetime(
|
value_type v1(toml::offset_datetime(
|
||||||
toml::local_date{2018, toml::month_t::Apr, 1},
|
toml::local_date{2018, toml::month_t::Apr, 1},
|
||||||
toml::local_time{12, 30, 0},
|
toml::local_time{12, 30, 0},
|
||||||
toml::time_offset{-8, 0}));
|
toml::time_offset{-8, 0}));
|
||||||
@@ -352,14 +366,14 @@ BOOST_AUTO_TEST_CASE(test_get_toml_offset_datetime)
|
|||||||
|
|
||||||
// get time_t as gmtime (2018-04-01T03:30:00Z)
|
// get time_t as gmtime (2018-04-01T03:30:00Z)
|
||||||
const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe!
|
const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe!
|
||||||
BOOST_CHECK(tmp);
|
BOOST_TEST(tmp);
|
||||||
const auto tm = *tmp;
|
const auto tm = *tmp;
|
||||||
BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018);
|
BOOST_TEST(tm.tm_year + 1900 == 2018);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4);
|
BOOST_TEST(tm.tm_mon + 1 == 4);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_mday, 1);
|
BOOST_TEST(tm.tm_mday == 1);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_hour, 20);
|
BOOST_TEST(tm.tm_hour == 20);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_min, 30);
|
BOOST_TEST(tm.tm_min == 30);
|
||||||
BOOST_CHECK_EQUAL(tm.tm_sec, 0);
|
BOOST_TEST(tm.tm_sec == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
360
tests/test_get_or.cpp
Normal file
360
tests/test_get_or.cpp
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_get_or"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using test_value_types = std::tuple<
|
||||||
|
toml::value,
|
||||||
|
toml::basic_value<toml::preserve_comments>,
|
||||||
|
toml::basic_value<toml::discard_comments, std::map, std::deque>,
|
||||||
|
toml::basic_value<toml::preserve_comments, std::map, std::deque>
|
||||||
|
>;
|
||||||
|
|
||||||
|
namespace test
|
||||||
|
{
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::vector<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::deque<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits, typename T, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const std::list<T, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << i << ' ';}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits,
|
||||||
|
typename Key, typename Value, typename Comp, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
|
const std::map<Key, Value, Comp, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template<typename charT, typename traits,
|
||||||
|
typename Key, typename Value, typename Hash, typename Eq, typename Alloc>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os,
|
||||||
|
const std::unordered_map<Key, Value, Hash, Eq, Alloc>& v)
|
||||||
|
{
|
||||||
|
os << "[ ";
|
||||||
|
for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";}
|
||||||
|
os << ']';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
} // test
|
||||||
|
|
||||||
|
#define TOML11_TEST_GET_OR_EXACT(toml_type, init_expr, opt_expr)\
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
const toml::toml_type init init_expr ; \
|
||||||
|
const toml::toml_type opt opt_expr ; \
|
||||||
|
const value_type v(init); \
|
||||||
|
BOOST_TEST(init != opt); \
|
||||||
|
BOOST_TEST(init == toml::get_or(v, opt)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_exact, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
TOML11_TEST_GET_OR_EXACT(boolean, ( true), (false))
|
||||||
|
TOML11_TEST_GET_OR_EXACT(integer, ( 42), ( 54))
|
||||||
|
TOML11_TEST_GET_OR_EXACT(floating, ( 3.14), ( 2.71))
|
||||||
|
TOML11_TEST_GET_OR_EXACT(string, ("foo"), ("bar"))
|
||||||
|
TOML11_TEST_GET_OR_EXACT(local_time, (12, 30, 45), (6, 0, 30))
|
||||||
|
TOML11_TEST_GET_OR_EXACT(local_date, (2019, toml::month_t::Apr, 1),
|
||||||
|
(1999, toml::month_t::Jan, 2))
|
||||||
|
TOML11_TEST_GET_OR_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_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};
|
||||||
|
const typename value_type::array_type opt {6,7,8,9,10};
|
||||||
|
const value_type v(init);
|
||||||
|
BOOST_TEST(init != opt);
|
||||||
|
BOOST_TEST(init == toml::get_or(v, opt));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
const typename value_type::table_type opt {{"key1", 54}, {"key2", "bar"}};
|
||||||
|
const value_type v(init);
|
||||||
|
BOOST_TEST(init != opt);
|
||||||
|
BOOST_TEST(init == toml::get_or(v, opt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_GET_OR_EXACT
|
||||||
|
|
||||||
|
#define TOML11_TEST_GET_OR_MODIFY(toml_type, init_expr, opt_expr)\
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
const toml::toml_type init init_expr ; \
|
||||||
|
toml::toml_type opt1 opt_expr ; \
|
||||||
|
toml::toml_type opt2 opt_expr ; \
|
||||||
|
value_type v(init); \
|
||||||
|
BOOST_TEST(init != opt1); \
|
||||||
|
toml::get_or(v, opt2) = opt1; \
|
||||||
|
BOOST_TEST(opt1 == toml::get<toml::toml_type>(v)); \
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_modify, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(boolean, ( true), (false))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(integer, ( 42), ( 54))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(floating, ( 3.14), ( 2.71))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(string, ("foo"), ("bar"))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(local_time, (12, 30, 45), (6, 0, 30))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(local_date, (2019, toml::month_t::Apr, 1),
|
||||||
|
(1999, toml::month_t::Jan, 2))
|
||||||
|
TOML11_TEST_GET_OR_MODIFY(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_MODIFY(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 opt1{6,7,8,9,10};
|
||||||
|
typename value_type::array_type opt2{6,7,8,9,10};
|
||||||
|
BOOST_TEST(init != opt1);
|
||||||
|
value_type v(init);
|
||||||
|
toml::get_or(v, opt2) = opt1;
|
||||||
|
BOOST_TEST(opt1 == toml::get<typename value_type::array_type>(v));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
typename value_type::table_type init{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
typename value_type::table_type opt1{{"key1", 54}, {"key2", "bar"}};
|
||||||
|
typename value_type::table_type opt2{{"key1", 54}, {"key2", "bar"}};
|
||||||
|
value_type v(init);
|
||||||
|
BOOST_TEST(init != opt1);
|
||||||
|
toml::get_or(v, opt2) = opt1;
|
||||||
|
BOOST_TEST(opt1 == toml::get<typename value_type::table_type>(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_GET_OR_MODIFY
|
||||||
|
|
||||||
|
#define TOML11_TEST_GET_OR_FALLBACK(init_type, opt_type) \
|
||||||
|
{ \
|
||||||
|
using namespace test; \
|
||||||
|
value_type v(init_type); \
|
||||||
|
BOOST_TEST(opt_type == toml::get_or(v, opt_type));\
|
||||||
|
} \
|
||||||
|
/**/
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_or_fallback, value_type, test_value_types)
|
||||||
|
{
|
||||||
|
const toml::boolean boolean (true);
|
||||||
|
const toml::integer integer (42);
|
||||||
|
const toml::floating floating (3.14);
|
||||||
|
const toml::string string ("foo");
|
||||||
|
const toml::local_time local_time (12, 30, 45);
|
||||||
|
const toml::local_date local_date (2019, toml::month_t::Apr, 1);
|
||||||
|
const toml::local_datetime local_datetime (
|
||||||
|
toml::local_date(2019, toml::month_t::Apr, 1),
|
||||||
|
toml::local_time(12, 30, 45));
|
||||||
|
const toml::offset_datetime offset_datetime(
|
||||||
|
toml::local_date(2019, toml::month_t::Apr, 1),
|
||||||
|
toml::local_time(12, 30, 45), toml::time_offset( 9, 0));
|
||||||
|
|
||||||
|
using array_type = typename value_type::array_type;
|
||||||
|
using table_type = typename value_type::table_type;
|
||||||
|
const array_type array{1, 2, 3, 4, 5};
|
||||||
|
const table_type table{{"key1", 42}, {"key2", "foo"}};
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(boolean, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(integer, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(floating, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(string, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_time, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_date, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(local_datetime, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, array );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(offset_datetime, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(array, table );
|
||||||
|
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, boolean );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, integer );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, floating );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, string );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, local_time );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, local_date );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, local_datetime );
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, offset_datetime);
|
||||||
|
TOML11_TEST_GET_OR_FALLBACK(table, array );
|
||||||
|
}
|
||||||
|
#undef TOML11_TEST_GET_OR_FALLBACK
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_get_or_integer)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
BOOST_TEST(42u == toml::get_or(v1, 0u));
|
||||||
|
BOOST_TEST(0u == toml::get_or(v2, 0u));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_get_or_floating)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1(42);
|
||||||
|
toml::value v2(3.14);
|
||||||
|
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_AUTO_TEST_CASE(test_get_or_string)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
toml::value v1("foobar");
|
||||||
|
toml::value v2(42);
|
||||||
|
|
||||||
|
std::string s1("bazqux");
|
||||||
|
const std::string s2("bazqux");
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::get_or(v1, s1));
|
||||||
|
BOOST_TEST("bazqux" == toml::get_or(v2, s1));
|
||||||
|
|
||||||
|
std::string& v1r = toml::get_or(v1, s1);
|
||||||
|
std::string& s1r = toml::get_or(v2, s1);
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == v1r);
|
||||||
|
BOOST_TEST("bazqux" == s1r);
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::get_or(v1, s2));
|
||||||
|
BOOST_TEST("bazqux" == toml::get_or(v2, s2));
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1)));
|
||||||
|
BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
toml::value v1("foobar");
|
||||||
|
toml::value v2(42);
|
||||||
|
|
||||||
|
BOOST_TEST("foobar" == toml::get_or(v1, "bazqux"));
|
||||||
|
BOOST_TEST("bazqux" == toml::get_or(v2, "bazqux"));
|
||||||
|
|
||||||
|
const char* lit = "bazqux";
|
||||||
|
BOOST_TEST("foobar" == toml::get_or(v1, lit));
|
||||||
|
BOOST_TEST("bazqux" == toml::get_or(v2, lit));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#define BOOST_TEST_MODULE "test_get_or"
|
|
||||||
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_TEST_NO_LIB
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
#endif
|
|
||||||
#include <toml.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <list>
|
|
||||||
#include <deque>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_find)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
toml::value v(true);
|
|
||||||
bool thrown = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
toml::find<toml::boolean>(v, "key");
|
|
||||||
}
|
|
||||||
catch(toml::type_error const& te)
|
|
||||||
{
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
BOOST_CHECK(thrown);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
toml::table v{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
|
||||||
toml::find<toml::integer>(v, "num") = 54;
|
|
||||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
toml::value v = toml::table{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::find<int>(v, "num"));
|
|
||||||
toml::find<toml::integer>(v, "num") = 54;
|
|
||||||
BOOST_CHECK_EQUAL(54, toml::find<int>(v, "num"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_get_or)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
toml::table v{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v = toml::table{{"num", 42}};
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v, "num", 0));
|
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v, "foo", 0));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
toml::value v1(42);
|
|
||||||
toml::value v2(3.14);
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::get_or<int>(v1, 0));
|
|
||||||
BOOST_CHECK_EQUAL(0, toml::get_or<int>(v2, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_expect)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
toml::value v1(42);
|
|
||||||
toml::value v2(3.14);
|
|
||||||
BOOST_CHECK_EQUAL(42, toml::expect<int>(v1).unwrap_or(0));
|
|
||||||
BOOST_CHECK_EQUAL( 0, toml::expect<int>(v2).unwrap_or(0));
|
|
||||||
BOOST_CHECK_EQUAL("42", toml::expect<int>(v1).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")));
|
|
||||||
BOOST_CHECK_EQUAL("none", toml::expect<int>(v2).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,17 +10,17 @@ do { \
|
|||||||
const std::string expected(expct); \
|
const std::string expected(expct); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location<std::string> loc("test", token); \
|
||||||
const auto result = lxr::invoke(loc); \
|
const auto result = lxr::invoke(loc); \
|
||||||
BOOST_CHECK(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
const auto region = result.unwrap(); \
|
const auto region = result.unwrap(); \
|
||||||
BOOST_CHECK_EQUAL(region.str(), expected); \
|
BOOST_TEST(region.str() == expected); \
|
||||||
BOOST_CHECK_EQUAL(region.str().size(), expected.size()); \
|
BOOST_TEST(region.str().size() == expected.size()); \
|
||||||
BOOST_CHECK_EQUAL(static_cast<std::size_t>(std::distance( \
|
BOOST_TEST(static_cast<std::size_t>(std::distance( \
|
||||||
loc.begin(), loc.iter())), region.size()); \
|
loc.begin(), loc.iter())) == region.size()); \
|
||||||
} else { \
|
} else { \
|
||||||
std::cerr << "lexer " << lxr::pattern() << " failed with input `"; \
|
std::cerr << "lexer failed with input `"; \
|
||||||
std::cerr << token << "`. expected `" << expected << "`\n"; \
|
std::cerr << token << "`. expected `" << expected << "`\n"; \
|
||||||
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
||||||
} \
|
} \
|
||||||
} while(false); \
|
} while(false); \
|
||||||
/**/
|
/**/
|
||||||
@@ -30,6 +30,7 @@ do { \
|
|||||||
const std::string token (tkn); \
|
const std::string token (tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location<std::string> loc("test", token); \
|
||||||
const auto result = lxr::invoke(loc); \
|
const auto result = lxr::invoke(loc); \
|
||||||
BOOST_CHECK(result.is_err()); \
|
BOOST_TEST(result.is_err()); \
|
||||||
BOOST_CHECK(loc.begin() == loc.iter()); \
|
const bool loc_same = (loc.begin() == loc.iter()); \
|
||||||
|
BOOST_TEST(loc_same); \
|
||||||
} while(false); /**/
|
} while(false); /**/
|
||||||
|
|||||||
163
tests/test_literals.cpp
Normal file
163
tests/test_literals.cpp
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_literals"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_file_as_literal)
|
||||||
|
{
|
||||||
|
using namespace toml::literals::toml_literals;
|
||||||
|
|
||||||
|
{
|
||||||
|
const toml::value r{{"a", 42}, {"b", "baz"}};
|
||||||
|
const toml::value v = u8R"(
|
||||||
|
a = 42
|
||||||
|
b = "baz"
|
||||||
|
)"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(r == v);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value r{
|
||||||
|
{"c", 3.14},
|
||||||
|
{"table", toml::table{{"a", 42}, {"b", "baz"}}}
|
||||||
|
};
|
||||||
|
const toml::value v = u8R"(
|
||||||
|
c = 3.14
|
||||||
|
[table]
|
||||||
|
a = 42
|
||||||
|
b = "baz"
|
||||||
|
)"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(r == v);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value r{
|
||||||
|
{"table", toml::table{{"a", 42}, {"b", "baz"}}}
|
||||||
|
};
|
||||||
|
const toml::value v = u8R"(
|
||||||
|
[table]
|
||||||
|
a = 42
|
||||||
|
b = "baz"
|
||||||
|
)"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(r == v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_value_as_literal)
|
||||||
|
{
|
||||||
|
using namespace toml::literals::toml_literals;
|
||||||
|
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"true"_toml;
|
||||||
|
const toml::value v2 = u8"false"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_boolean());
|
||||||
|
BOOST_TEST(v2.is_boolean());
|
||||||
|
BOOST_TEST(toml::get<bool>(v1));
|
||||||
|
BOOST_TEST(!toml::get<bool>(v2));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"123_456"_toml;
|
||||||
|
const toml::value v2 = u8"0b0010"_toml;
|
||||||
|
const toml::value v3 = u8"0xDEADBEEF"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_integer());
|
||||||
|
BOOST_TEST(v2.is_integer());
|
||||||
|
BOOST_TEST(v3.is_integer());
|
||||||
|
BOOST_TEST(toml::get<toml::integer>(v1) == 123456);
|
||||||
|
BOOST_TEST(toml::get<toml::integer>(v2) == 2);
|
||||||
|
BOOST_TEST(toml::get<toml::integer>(v3) == 0xDEADBEEF);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"3.1415"_toml;
|
||||||
|
const toml::value v2 = u8"6.02e+23"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_floating());
|
||||||
|
BOOST_TEST(v2.is_floating());
|
||||||
|
BOOST_TEST(toml::get<double>(v1) == 3.1415, boost::test_tools::tolerance(0.00001));
|
||||||
|
BOOST_TEST(toml::get<double>(v2) == 6.02e23, boost::test_tools::tolerance(0.0001));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8R"("foo")"_toml;
|
||||||
|
const toml::value v2 = u8R"('foo')"_toml;
|
||||||
|
const toml::value v3 = u8R"("""foo""")"_toml;
|
||||||
|
const toml::value v4 = u8R"('''foo''')"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_string());
|
||||||
|
BOOST_TEST(v2.is_string());
|
||||||
|
BOOST_TEST(v3.is_string());
|
||||||
|
BOOST_TEST(v4.is_string());
|
||||||
|
BOOST_TEST(toml::get<std::string>(v1) == "foo");
|
||||||
|
BOOST_TEST(toml::get<std::string>(v2) == "foo");
|
||||||
|
BOOST_TEST(toml::get<std::string>(v3) == "foo");
|
||||||
|
BOOST_TEST(toml::get<std::string>(v4) == "foo");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8R"([1,2,3])"_toml;
|
||||||
|
BOOST_TEST(v1.is_array());
|
||||||
|
const bool result = (toml::get<std::vector<int>>(v1) == std::vector<int>{1,2,3});
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v2 = u8R"([1,])"_toml;
|
||||||
|
BOOST_TEST(v2.is_array());
|
||||||
|
const bool result = (toml::get<std::vector<int>>(v2) == std::vector<int>{1});
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v3 = u8R"([[1,]])"_toml;
|
||||||
|
BOOST_TEST(v3.is_array());
|
||||||
|
const bool result = (toml::get<std::vector<int>>(toml::get<toml::array>(v3).front()) == std::vector<int>{1});
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v4 = u8R"([[1],])"_toml;
|
||||||
|
BOOST_TEST(v4.is_array());
|
||||||
|
const bool result = (toml::get<std::vector<int>>(toml::get<toml::array>(v4).front()) == std::vector<int>{1});
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8R"({a = 42})"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_table());
|
||||||
|
const bool result = toml::get<std::map<std::string,int>>(v1) ==
|
||||||
|
std::map<std::string,int>{{"a", 42}};
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"1979-05-27"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_local_date());
|
||||||
|
BOOST_TEST(toml::get<toml::local_date>(v1) ==
|
||||||
|
toml::local_date(1979, toml::month_t::May, 27));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"12:00:00"_toml;
|
||||||
|
|
||||||
|
BOOST_TEST(v1.is_local_time());
|
||||||
|
const bool result = toml::get<std::chrono::hours>(v1) == std::chrono::hours(12);
|
||||||
|
BOOST_TEST(result);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = u8"1979-05-27T07:32:00"_toml;
|
||||||
|
BOOST_TEST(v1.is_local_datetime());
|
||||||
|
BOOST_TEST(toml::get<toml::local_datetime>(v1) ==
|
||||||
|
toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
|
toml::local_time(7, 32, 0)));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const toml::value v1 = "1979-05-27T07:32:00Z"_toml;
|
||||||
|
BOOST_TEST(v1.is_offset_datetime());
|
||||||
|
BOOST_TEST(toml::get<toml::offset_datetime>(v1) ==
|
||||||
|
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
11
tests/test_multiple_translation_unit_1.cpp
Normal file
11
tests/test_multiple_translation_unit_1.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <toml.hpp>
|
||||||
|
|
||||||
|
int read_a(const toml::table&);
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const std::string content("a = 0");
|
||||||
|
std::istringstream iss(content);
|
||||||
|
const auto data = toml::parse(iss, "test_multiple_translation_unit.toml");
|
||||||
|
return read_a(toml::get<toml::table>(data));
|
||||||
|
}
|
||||||
6
tests/test_multiple_translation_unit_2.cpp
Normal file
6
tests/test_multiple_translation_unit_2.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include <toml.hpp>
|
||||||
|
|
||||||
|
int read_a(const toml::table& t)
|
||||||
|
{
|
||||||
|
return toml::get<int>(t.at("a"));
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#define BOOST_TEST_MODULE "parse_array_test"
|
#define BOOST_TEST_MODULE "parse_array<toml::value>_test"
|
||||||
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#else
|
#else
|
||||||
@@ -13,118 +13,118 @@ using namespace detail;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_oneline_array)
|
BOOST_AUTO_TEST_CASE(test_oneline_array)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[]", array());
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[]", array());
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[3,1,4,1,5]", a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\"]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[\"foo\", \"bar\", \"baz\"]", a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5,]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[3,1,4,1,5,]", a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\",]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[\"foo\", \"bar\", \"baz\",]", a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_oneline_array_value)
|
BOOST_AUTO_TEST_CASE(test_oneline_array_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[]", toml::value(array()));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[]", toml::value(array()));
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[3,1,4,1,5]", toml::value(a));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\"]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[\"foo\", \"bar\", \"baz\"]", toml::value(a));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5,]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[3,1,4,1,5,]", toml::value(a));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\", \"bar\", \"baz\",]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[\"foo\", \"bar\", \"baz\",]", toml::value(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_multiline_array)
|
BOOST_AUTO_TEST_CASE(test_multiline_array)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[\n#comment\n]", array());
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[\n#comment\n]", array());
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[3,\n1,\n4,\n1,\n5]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[3,\n1,\n4,\n1,\n5]", a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",\n\"bar\",\n\"baz\"]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[\"foo\",\n\"bar\",\n\"baz\"]", a);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", a);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("b#r");
|
a[0] = toml::value("foo"); a[1] = toml::value("b#r");
|
||||||
a[2] = toml::value("b#z");
|
a[2] = toml::value("b#z");
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a);
|
TOML11_TEST_PARSE_EQUAL(parse_array<toml::value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_multiline_array_value)
|
BOOST_AUTO_TEST_CASE(test_multiline_array_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\n#comment\n]", toml::value(array()));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[\n#comment\n]", toml::value(array()));
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,\n1,\n4,\n1,\n5]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[3,\n1,\n4,\n1,\n5]", toml::value(a));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
a[0] = toml::value("foo"); a[1] = toml::value("bar");
|
||||||
a[2] = toml::value("baz");
|
a[2] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",\n\"bar\",\n\"baz\"]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[\"foo\",\n\"bar\",\n\"baz\"]", toml::value(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
array a(5);
|
array a(5);
|
||||||
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
a[0] = toml::value(3); a[1] = toml::value(1); a[2] = toml::value(4);
|
||||||
a[3] = toml::value(1); a[4] = toml::value(5);
|
a[3] = toml::value(1); a[4] = toml::value(5);
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", toml::value(a));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
array a(3);
|
array a(3);
|
||||||
a[0] = toml::value("foo"); a[1] = toml::value("b#r");
|
a[0] = toml::value("foo"); a[1] = toml::value("b#r");
|
||||||
a[2] = toml::value("b#z");
|
a[2] = toml::value("b#z");
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", toml::value(a));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", toml::value(a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <toml/region.hpp>
|
#include <toml.hpp>
|
||||||
#include <toml/result.hpp>
|
|
||||||
|
|
||||||
// some of the parsers returns not only a value but also a region.
|
// some of the parsers returns not only a value but also a region.
|
||||||
#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \
|
#define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \
|
||||||
@@ -10,13 +9,13 @@ do { \
|
|||||||
const std::string token(tkn); \
|
const std::string token(tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location<std::string> loc("test", token); \
|
||||||
const auto result = psr(loc); \
|
const auto result = psr(loc); \
|
||||||
BOOST_CHECK(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
BOOST_CHECK(result.unwrap().first == expct); \
|
BOOST_TEST(result.unwrap().first == expct); \
|
||||||
} else { \
|
} else { \
|
||||||
std::cerr << "parser " << #psr << " failed with input `"; \
|
std::cerr << "parser " << #psr << " failed with input `"; \
|
||||||
std::cerr << token << "`.\n"; \
|
std::cerr << token << "`.\n"; \
|
||||||
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
||||||
} \
|
} \
|
||||||
} while(false); \
|
} while(false); \
|
||||||
/**/
|
/**/
|
||||||
@@ -26,13 +25,13 @@ do { \
|
|||||||
const std::string token(tkn); \
|
const std::string token(tkn); \
|
||||||
toml::detail::location<std::string> loc("test", token); \
|
toml::detail::location<std::string> loc("test", token); \
|
||||||
const auto result = psr(loc); \
|
const auto result = psr(loc); \
|
||||||
BOOST_CHECK(result.is_ok()); \
|
BOOST_TEST(result.is_ok()); \
|
||||||
if(result.is_ok()){ \
|
if(result.is_ok()){ \
|
||||||
BOOST_CHECK(result.unwrap() == expct); \
|
BOOST_TEST(result.unwrap() == expct); \
|
||||||
} else { \
|
} else { \
|
||||||
std::cerr << "parse_value failed with input `"; \
|
std::cerr << "parse_value failed with input `"; \
|
||||||
std::cerr << token << "`.\n"; \
|
std::cerr << token << "`.\n"; \
|
||||||
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
std::cerr << "reason: " << result.unwrap_err() << '\n'; \
|
||||||
} \
|
} \
|
||||||
} while(false); \
|
} while(false); \
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ BOOST_AUTO_TEST_CASE(test_boolean)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_boolean_value)
|
BOOST_AUTO_TEST_CASE(test_boolean_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "true", toml::value( true));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "true", toml::value( true));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "false", toml::value(false));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "false", toml::value(false));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ BOOST_AUTO_TEST_CASE(test_time)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_time_value)
|
BOOST_AUTO_TEST_CASE(test_time_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00", toml::value(toml::local_time(7, 32, 0)));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "07:32:00", toml::value(toml::local_time(7, 32, 0)));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.99", toml::value(toml::local_time(7, 32, 0, 990, 0)));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "07:32:00.99", toml::value(toml::local_time(7, 32, 0, 990, 0)));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999", toml::value(toml::local_time(7, 32, 0, 999, 0)));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "07:32:00.999", toml::value(toml::local_time(7, 32, 0, 999, 0)));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999)));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999)));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_date)
|
BOOST_AUTO_TEST_CASE(test_date)
|
||||||
@@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(test_date)
|
|||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_date_value)
|
BOOST_AUTO_TEST_CASE(test_date_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27",
|
||||||
value(toml::local_date(1979, toml::month_t::May, 27)));
|
value(toml::local_date(1979, toml::month_t::May, 27)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,25 +64,25 @@ BOOST_AUTO_TEST_CASE(test_datetime)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_datetime_value)
|
BOOST_AUTO_TEST_CASE(test_datetime_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.99",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.999999",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
||||||
|
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27t07:32:00",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.99",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27t07:32:00.99",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.999999",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27t07:32:00.999999",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
||||||
|
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27 07:32:00",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.99",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27 07:32:00.99",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 990, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.999999",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27 07:32:00.999999",
|
||||||
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
toml::value(toml::local_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0, 999, 999))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,23 +111,23 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_offset_datetime_value)
|
BOOST_AUTO_TEST_CASE(test_offset_datetime_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00Z",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00Z",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0), toml::time_offset(0, 0))));
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99Z",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.99Z",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0))));
|
toml::local_time(7, 32, 0, 990, 0), toml::time_offset(0, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999Z",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.999999Z",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0))));
|
toml::local_time(7, 32, 0, 999, 999), toml::time_offset(0, 0))));
|
||||||
|
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00+09:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00+09:00",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0), toml::time_offset(9, 0))));
|
toml::local_time(7, 32, 0), toml::time_offset(9, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99+09:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.99+09:00",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0))));
|
toml::local_time(7, 32, 0, 990, 0), toml::time_offset(9, 0))));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999+09:00",
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1979-05-27T07:32:00.999999+09:00",
|
||||||
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::value(toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0))));
|
toml::local_time(7, 32, 0, 999, 999), toml::time_offset(9, 0))));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,73 +8,69 @@
|
|||||||
#include <toml.hpp>
|
#include <toml.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <map>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_example)
|
BOOST_AUTO_TEST_CASE(test_example)
|
||||||
{
|
{
|
||||||
const auto data = toml::parse("toml/tests/example.toml");
|
const auto data = toml::parse("toml/tests/example.toml");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(data.at("title")), "TOML Example");
|
BOOST_TEST(toml::find<std::string>(data, "title") == "TOML Example");
|
||||||
toml::Table owner = toml::get<toml::Table>(data.at("owner"));
|
const auto& owner = toml::find(data, "owner");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("name")), "Tom Preston-Werner");
|
BOOST_TEST(toml::find<std::string>(owner, "name") == "Tom Preston-Werner");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("organization")), "GitHub");
|
BOOST_TEST(toml::find<std::string>(owner, "organization") == "GitHub");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("bio")),
|
BOOST_TEST(toml::find<std::string>(owner, "bio") ==
|
||||||
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
||||||
BOOST_CHECK_EQUAL(toml::get<toml::Datetime>(owner.at("dob")),
|
BOOST_TEST(toml::find<toml::offset_datetime>(owner, "dob") ==
|
||||||
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table database = toml::get<toml::Table>(data.at("database"));
|
const auto& database = toml::find(data, "database");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(database.at("server")), "192.168.1.1");
|
BOOST_TEST(toml::find<std::string>(database, "server") == "192.168.1.1");
|
||||||
const std::vector<int> expected_ports{8001, 8001, 8002};
|
const std::vector<int> expected_ports{8001, 8001, 8002};
|
||||||
BOOST_CHECK(toml::get<std::vector<int>>(database.at("ports")) == expected_ports);
|
BOOST_CHECK(toml::find<std::vector<int>>(database, "ports") == expected_ports);
|
||||||
BOOST_CHECK_EQUAL(toml::get<int>(database.at("connection_max")), 5000);
|
BOOST_TEST(toml::find<int >(database, "connection_max") == 5000);
|
||||||
BOOST_CHECK_EQUAL(toml::get<bool>(database.at("enabled")), true);
|
BOOST_TEST(toml::find<bool>(database, "enabled") == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table servers = toml::get<toml::Table>(data.at("servers"));
|
const auto& servers = toml::find(data, "servers");
|
||||||
{
|
{
|
||||||
toml::Table alpha = toml::get<toml::Table>(servers.at("alpha"));
|
toml::table alpha = toml::find<toml::table>(servers, "alpha");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("ip")), "10.0.0.1");
|
BOOST_TEST(toml::get<std::string>(alpha.at("ip")) == "10.0.0.1");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("dc")), "eqdc10");
|
BOOST_TEST(toml::get<std::string>(alpha.at("dc")) == "eqdc10");
|
||||||
|
|
||||||
toml::Table beta = toml::get<toml::Table>(servers.at("beta"));
|
toml::table beta = toml::find<toml::table>(servers, "beta");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("ip")), "10.0.0.2");
|
BOOST_TEST(toml::get<std::string>(beta.at("ip")) == "10.0.0.2");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("dc")), "eqdc10");
|
BOOST_TEST(toml::get<std::string>(beta.at("dc")) == "eqdc10");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD");
|
BOOST_TEST(toml::get<std::string>(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD");
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table clients = toml::get<toml::Table>(data.at("clients"));
|
const auto& clients = toml::find(data, "clients");
|
||||||
{
|
{
|
||||||
toml::Array clients_data = toml::get<toml::Array>(clients.at("data"));
|
toml::array clients_data = toml::find<toml::array>(clients, "data");
|
||||||
|
|
||||||
std::vector<std::string> expected_name{"gamma", "delta"};
|
std::vector<std::string> expected_name{"gamma", "delta"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) == expected_name);
|
||||||
expected_name);
|
|
||||||
std::vector<int> expected_number{1, 2};
|
std::vector<int> expected_number{1, 2};
|
||||||
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) ==
|
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) == expected_number);
|
||||||
expected_number);
|
|
||||||
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(clients.at("hosts")) ==
|
BOOST_CHECK(toml::find<std::vector<std::string>>(clients, "hosts") == expected_hosts);
|
||||||
expected_hosts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<toml::Table> products =
|
std::vector<toml::table> products =
|
||||||
toml::get<std::vector<toml::Table>>(data.at("products"));
|
toml::find<std::vector<toml::table>>(data, "products");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(0).at("name")),
|
BOOST_TEST(toml::get<std::string>(products.at(0).at("name")) == "Hammer");
|
||||||
"Hammer");
|
BOOST_TEST(toml::get<std::int64_t>(products.at(0).at("sku")) == 738594937);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(0).at("sku")),
|
|
||||||
738594937);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("name")),
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("name")) == "Nail");
|
||||||
"Nail");
|
BOOST_TEST(toml::get<std::int64_t>(products.at(1).at("sku")) == 284758393);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(1).at("sku")),
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("color")) == "gray");
|
||||||
284758393);
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("color")),
|
|
||||||
"gray");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,42 +79,194 @@ BOOST_AUTO_TEST_CASE(test_example_stream)
|
|||||||
std::ifstream ifs("toml/tests/example.toml");
|
std::ifstream ifs("toml/tests/example.toml");
|
||||||
const auto data = toml::parse(ifs);
|
const auto data = toml::parse(ifs);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(data.at("title")), "TOML Example");
|
BOOST_TEST(toml::find<std::string>(data, "title") == "TOML Example");
|
||||||
toml::Table owner = toml::get<toml::Table>(data.at("owner"));
|
const auto& owner = toml::find(data, "owner");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("name")), "Tom Preston-Werner");
|
BOOST_TEST(toml::find<std::string>(owner, "name") == "Tom Preston-Werner");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("organization")), "GitHub");
|
BOOST_TEST(toml::find<std::string>(owner, "organization") == "GitHub");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(owner.at("bio")),
|
BOOST_TEST(toml::find<std::string>(owner, "bio") ==
|
||||||
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
||||||
BOOST_CHECK_EQUAL(toml::get<toml::Datetime>(owner.at("dob")),
|
BOOST_TEST(toml::find<toml::offset_datetime>(owner, "dob") ==
|
||||||
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table database = toml::get<toml::Table>(data.at("database"));
|
const auto& database = toml::find(data, "database");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(database.at("server")), "192.168.1.1");
|
BOOST_TEST(toml::find<std::string>(database, "server") == "192.168.1.1");
|
||||||
const std::vector<int> expected_ports{8001, 8001, 8002};
|
const std::vector<int> expected_ports{8001, 8001, 8002};
|
||||||
BOOST_CHECK(toml::get<std::vector<int>>(database.at("ports")) == expected_ports);
|
BOOST_CHECK(toml::find<std::vector<int>>(database, "ports") == expected_ports);
|
||||||
BOOST_CHECK_EQUAL(toml::get<int>(database.at("connection_max")), 5000);
|
BOOST_TEST(toml::find<int >(database, "connection_max") == 5000);
|
||||||
BOOST_CHECK_EQUAL(toml::get<bool>(database.at("enabled")), true);
|
BOOST_TEST(toml::find<bool>(database, "enabled") == true);
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table servers = toml::get<toml::Table>(data.at("servers"));
|
const auto& servers = toml::find(data, "servers");
|
||||||
{
|
{
|
||||||
toml::Table alpha = toml::get<toml::Table>(servers.at("alpha"));
|
toml::table alpha = toml::find<toml::table>(servers, "alpha");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("ip")), "10.0.0.1");
|
BOOST_TEST(toml::get<std::string>(alpha.at("ip")) == "10.0.0.1");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(alpha.at("dc")), "eqdc10");
|
BOOST_TEST(toml::get<std::string>(alpha.at("dc")) == "eqdc10");
|
||||||
|
|
||||||
toml::Table beta = toml::get<toml::Table>(servers.at("beta"));
|
toml::table beta = toml::find<toml::table>(servers, "beta");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("ip")), "10.0.0.2");
|
BOOST_TEST(toml::get<std::string>(beta.at("ip")) == "10.0.0.2");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("dc")), "eqdc10");
|
BOOST_TEST(toml::get<std::string>(beta.at("dc")) == "eqdc10");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD");
|
BOOST_TEST(toml::get<std::string>(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD");
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::Table clients = toml::get<toml::Table>(data.at("clients"));
|
const auto& clients = toml::find(data, "clients");
|
||||||
{
|
{
|
||||||
toml::Array clients_data = toml::get<toml::Array>(clients.at("data"));
|
toml::array clients_data = toml::find<toml::array>(clients, "data");
|
||||||
|
std::vector<std::string> expected_name{"gamma", "delta"};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) == expected_name);
|
||||||
|
|
||||||
|
std::vector<int> expected_number{1, 2};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) == expected_number);
|
||||||
|
|
||||||
|
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(clients, "hosts") == expected_hosts);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<toml::table> products =
|
||||||
|
toml::find<std::vector<toml::table>>(data, "products");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(0).at("name")) ==
|
||||||
|
"Hammer");
|
||||||
|
BOOST_TEST(toml::get<std::int64_t>(products.at(0).at("sku")) ==
|
||||||
|
738594937);
|
||||||
|
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("name")) ==
|
||||||
|
"Nail");
|
||||||
|
BOOST_TEST(toml::get<std::int64_t>(products.at(1).at("sku")) ==
|
||||||
|
284758393);
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("color")) ==
|
||||||
|
"gray");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/fruit.toml");
|
||||||
|
const auto blah = toml::find<toml::array>(toml::find(data, "fruit"), "blah");
|
||||||
|
BOOST_TEST(toml::find<std::string>(blah.at(0), "name") == "apple");
|
||||||
|
BOOST_TEST(toml::find<std::string>(blah.at(1), "name") == "banana");
|
||||||
|
{
|
||||||
|
const auto physical = toml::find(blah.at(0), "physical");
|
||||||
|
BOOST_TEST(toml::find<std::string>(physical, "color") == "red");
|
||||||
|
BOOST_TEST(toml::find<std::string>(physical, "shape") == "round");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const auto physical = toml::find(blah.at(1), "physical");
|
||||||
|
BOOST_TEST(toml::find<std::string>(physical, "color") == "yellow");
|
||||||
|
BOOST_TEST(toml::find<std::string>(physical, "shape") == "bent");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hard_example)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/hard_example.toml");
|
||||||
|
const auto the = toml::find(data, "the");
|
||||||
|
BOOST_TEST(toml::find<std::string>(the, "test_string") ==
|
||||||
|
"You'll hate me after this - #");
|
||||||
|
|
||||||
|
const auto hard = toml::find(the, "hard");
|
||||||
|
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(hard, "test_array") ==
|
||||||
|
expected_the_hard_test_array);
|
||||||
|
const std::vector<std::string> expected_the_hard_test_array2{
|
||||||
|
"Test #11 ]proved that", "Experiment #9 was a success"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(hard, "test_array2") ==
|
||||||
|
expected_the_hard_test_array2);
|
||||||
|
BOOST_TEST(toml::find<std::string>(hard, "another_test_string") ==
|
||||||
|
" Same thing, but with a string #");
|
||||||
|
BOOST_TEST(toml::find<std::string>(hard, "harder_test_string") ==
|
||||||
|
" And when \"'s are in the string, along with # \"");
|
||||||
|
|
||||||
|
const auto bit = toml::find(hard, "bit#");
|
||||||
|
BOOST_TEST(toml::find<std::string>(bit, "what?") ==
|
||||||
|
"You don't think some user won't do that?");
|
||||||
|
const std::vector<std::string> expected_multi_line_array{"]"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(bit, "multi_line_array") ==
|
||||||
|
expected_multi_line_array);
|
||||||
|
}
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hard_example_comment)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments>("toml/tests/hard_example.toml");
|
||||||
|
const auto the = toml::find(data, "the");
|
||||||
|
BOOST_TEST(toml::find<std::string>(the, "test_string") ==
|
||||||
|
"You'll hate me after this - #");
|
||||||
|
|
||||||
|
const auto hard = toml::find(the, "hard");
|
||||||
|
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(hard, "test_array") ==
|
||||||
|
expected_the_hard_test_array);
|
||||||
|
const std::vector<std::string> expected_the_hard_test_array2{
|
||||||
|
"Test #11 ]proved that", "Experiment #9 was a success"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(hard, "test_array2") ==
|
||||||
|
expected_the_hard_test_array2);
|
||||||
|
BOOST_TEST(toml::find<std::string>(hard, "another_test_string") ==
|
||||||
|
" Same thing, but with a string #");
|
||||||
|
BOOST_TEST(toml::find<std::string>(hard, "harder_test_string") ==
|
||||||
|
" And when \"'s are in the string, along with # \"");
|
||||||
|
|
||||||
|
const auto bit = toml::find(hard, "bit#");
|
||||||
|
BOOST_TEST(toml::find<std::string>(bit, "what?") ==
|
||||||
|
"You don't think some user won't do that?");
|
||||||
|
const std::vector<std::string> expected_multi_line_array{"]"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(bit, "multi_line_array") ==
|
||||||
|
expected_multi_line_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example_preserve_comment)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments>("toml/tests/example.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "title") == "TOML Example");
|
||||||
|
const auto& owner = toml::find(data, "owner");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::find<std::string>(owner, "name") == "Tom Preston-Werner");
|
||||||
|
BOOST_TEST(toml::find<std::string>(owner, "organization") == "GitHub");
|
||||||
|
BOOST_TEST(toml::find<std::string>(owner, "bio") ==
|
||||||
|
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
||||||
|
BOOST_TEST(toml::find<toml::offset_datetime>(owner, "dob") ==
|
||||||
|
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||||
|
BOOST_TEST(toml::find(owner, "dob").comments().at(0) ==
|
||||||
|
" First class dates? Why not?");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& database = toml::find(data, "database");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::find<std::string>(database, "server") == "192.168.1.1");
|
||||||
|
const std::vector<int> expected_ports{8001, 8001, 8002};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<int>>(database, "ports") == expected_ports);
|
||||||
|
BOOST_TEST(toml::find<int >(database, "connection_max") == 5000);
|
||||||
|
BOOST_TEST(toml::find<bool>(database, "enabled") == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& servers = toml::find(data, "servers");
|
||||||
|
{
|
||||||
|
const auto& alpha = toml::find(servers, "alpha");
|
||||||
|
BOOST_TEST(alpha.comments().at(0) ==
|
||||||
|
" You can indent as you please. Tabs or spaces. TOML don't care.");
|
||||||
|
BOOST_TEST(toml::find<std::string>(alpha, "ip") == "10.0.0.1");
|
||||||
|
BOOST_TEST(toml::find<std::string>(alpha, "dc") == "eqdc10");
|
||||||
|
|
||||||
|
const auto& beta = toml::find(servers, "beta");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "ip") == "10.0.0.2");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "dc") == "eqdc10");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "country") ==
|
||||||
|
"\xE4\xB8\xAD\xE5\x9B\xBD");
|
||||||
|
BOOST_TEST(toml::find(beta, "country").comments().at(0) ==
|
||||||
|
" This should be parsed as UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& clients = toml::find(data, "clients");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::find(clients, "data").comments().at(0) ==
|
||||||
|
" just an update to make sure parsers support it");
|
||||||
|
|
||||||
|
|
||||||
|
toml::array clients_data = toml::find<toml::array>(clients, "data");
|
||||||
std::vector<std::string> expected_name{"gamma", "delta"};
|
std::vector<std::string> expected_name{"gamma", "delta"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) ==
|
||||||
expected_name);
|
expected_name);
|
||||||
@@ -126,71 +274,618 @@ BOOST_AUTO_TEST_CASE(test_example_stream)
|
|||||||
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) ==
|
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) ==
|
||||||
expected_number);
|
expected_number);
|
||||||
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(clients.at("hosts")) ==
|
BOOST_CHECK(toml::find<std::vector<std::string>>(clients, "hosts") ==
|
||||||
expected_hosts);
|
expected_hosts);
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find(clients, "hosts").comments().at(0) ==
|
||||||
|
" Line breaks are OK when inside arrays");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<toml::Table> products =
|
std::vector<toml::table> products =
|
||||||
toml::get<std::vector<toml::Table>>(data.at("products"));
|
toml::find<std::vector<toml::table>>(data, "products");
|
||||||
{
|
{
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(0).at("name")),
|
BOOST_TEST(toml::get<std::string>(products.at(0).at("name")) ==
|
||||||
"Hammer");
|
"Hammer");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(0).at("sku")),
|
BOOST_TEST(toml::get<std::int64_t>(products.at(0).at("sku")) ==
|
||||||
738594937);
|
738594937);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("name")),
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("name")) ==
|
||||||
"Nail");
|
"Nail");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(products.at(1).at("sku")),
|
BOOST_TEST(toml::get<std::int64_t>(products.at(1).at("sku")) ==
|
||||||
284758393);
|
284758393);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(products.at(1).at("color")),
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("color")) ==
|
||||||
"gray");
|
"gray");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque)
|
||||||
BOOST_AUTO_TEST_CASE(test_fruit)
|
|
||||||
{
|
{
|
||||||
const auto data = toml::parse("toml/tests/fruit.toml");
|
const auto data = toml::parse<toml::preserve_comments, std::map, std::deque
|
||||||
const auto blah = toml::get<std::vector<toml::Table>>(
|
>("toml/tests/example.toml");
|
||||||
toml::get<toml::Table>(data.at("fruit")).at("blah"));
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(blah.at(0).at("name")), "apple");
|
static_assert(std::is_same<typename decltype(data)::table_type,
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(blah.at(1).at("name")), "banana");
|
std::map<toml::key, typename std::remove_cv<decltype(data)>::type>
|
||||||
|
>::value, "");
|
||||||
|
static_assert(std::is_same<typename decltype(data)::array_type,
|
||||||
|
std::deque<typename std::remove_cv<decltype(data)>::type>
|
||||||
|
>::value, "");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "title") == "TOML Example");
|
||||||
|
const auto& owner = toml::find(data, "owner");
|
||||||
{
|
{
|
||||||
const auto physical = toml::get<toml::Table>(blah.at(0).at("physical"));
|
BOOST_TEST(toml::find<std::string>(owner, "name") == "Tom Preston-Werner");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("color")), "red");
|
BOOST_TEST(toml::find<std::string>(owner, "organization") == "GitHub");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("shape")), "round");
|
BOOST_TEST(toml::find<std::string>(owner, "bio") ==
|
||||||
|
"GitHub Cofounder & CEO\nLikes tater tots and beer.");
|
||||||
|
BOOST_TEST(toml::find<toml::offset_datetime>(owner, "dob") ==
|
||||||
|
toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27),
|
||||||
|
toml::local_time(7, 32, 0), toml::time_offset(0, 0)));
|
||||||
|
BOOST_TEST(toml::find(owner, "dob").comments().at(0) ==
|
||||||
|
" First class dates? Why not?");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& database = toml::find(data, "database");
|
||||||
{
|
{
|
||||||
const auto physical = toml::get<toml::Table>(blah.at(1).at("physical"));
|
BOOST_TEST(toml::find<std::string>(database, "server") == "192.168.1.1");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("color")), "yellow");
|
const std::vector<int> expected_ports{8001, 8001, 8002};
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(physical.at("shape")), "bent");
|
BOOST_CHECK(toml::find<std::vector<int>>(database, "ports") == expected_ports);
|
||||||
|
BOOST_TEST(toml::find<int >(database, "connection_max") == 5000);
|
||||||
|
BOOST_TEST(toml::find<bool>(database, "enabled") == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& servers = toml::find(data, "servers");
|
||||||
|
{
|
||||||
|
const auto& alpha = toml::find(servers, "alpha");
|
||||||
|
BOOST_TEST(alpha.comments().at(0) ==
|
||||||
|
" You can indent as you please. Tabs or spaces. TOML don't care.");
|
||||||
|
BOOST_TEST(toml::find<std::string>(alpha, "ip") == "10.0.0.1");
|
||||||
|
BOOST_TEST(toml::find<std::string>(alpha, "dc") == "eqdc10");
|
||||||
|
|
||||||
|
const auto& beta = toml::find(servers, "beta");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "ip") == "10.0.0.2");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "dc") == "eqdc10");
|
||||||
|
BOOST_TEST(toml::find<std::string>(beta, "country") ==
|
||||||
|
"\xE4\xB8\xAD\xE5\x9B\xBD");
|
||||||
|
BOOST_TEST(toml::find(beta, "country").comments().at(0) ==
|
||||||
|
" This should be parsed as UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& clients = toml::find(data, "clients");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::find(clients, "data").comments().at(0) ==
|
||||||
|
" just an update to make sure parsers support it");
|
||||||
|
|
||||||
|
|
||||||
|
toml::array clients_data = toml::find<toml::array>(clients, "data");
|
||||||
|
std::vector<std::string> expected_name{"gamma", "delta"};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<std::string>>(clients_data.at(0)) ==
|
||||||
|
expected_name);
|
||||||
|
std::vector<int> expected_number{1, 2};
|
||||||
|
BOOST_CHECK(toml::get<std::vector<int>>(clients_data.at(1)) ==
|
||||||
|
expected_number);
|
||||||
|
std::vector<std::string> expected_hosts{"alpha", "omega"};
|
||||||
|
BOOST_CHECK(toml::find<std::vector<std::string>>(clients, "hosts") ==
|
||||||
|
expected_hosts);
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find(clients, "hosts").comments().at(0) ==
|
||||||
|
" Line breaks are OK when inside arrays");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<toml::table> products =
|
||||||
|
toml::find<std::vector<toml::table>>(data, "products");
|
||||||
|
{
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(0).at("name")) ==
|
||||||
|
"Hammer");
|
||||||
|
BOOST_TEST(toml::get<std::int64_t>(products.at(0).at("sku")) ==
|
||||||
|
738594937);
|
||||||
|
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("name")) ==
|
||||||
|
"Nail");
|
||||||
|
BOOST_TEST(toml::get<std::int64_t>(products.at(1).at("sku")) ==
|
||||||
|
284758393);
|
||||||
|
BOOST_TEST(toml::get<std::string>(products.at(1).at("color")) ==
|
||||||
|
"gray");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_hard_example)
|
// ---------------------------------------------------------------------------
|
||||||
|
// after here, the test codes generate the content of a file.
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_file_with_BOM)
|
||||||
{
|
{
|
||||||
const auto data = toml::parse("toml/tests/hard_example.toml");
|
{
|
||||||
const auto the = toml::get<toml::Table>(data.at("the"));
|
const std::string table(
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
|
"\xEF\xBB\xBF" // BOM
|
||||||
"You'll hate me after this - #");
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss, "test_file_with_BOM.toml");
|
||||||
|
|
||||||
const auto hard = toml::get<toml::Table>(the.at("hard"));
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
|
}
|
||||||
expected_the_hard_test_array);
|
{
|
||||||
const std::vector<std::string> expected_the_hard_test_array2{
|
const std::string table(
|
||||||
"Test #11 ]proved that", "Experiment #9 was a success"};
|
"\xEF\xBB\xBF" // BOM
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
|
"key = \"value\"\n"
|
||||||
expected_the_hard_test_array2);
|
"[table]\n"
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
|
"key = \"value\"\n"
|
||||||
" Same thing, but with a string #");
|
);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
|
{
|
||||||
" And when \"'s are in the string, along with # \"");
|
std::ofstream ofs("tmp.toml");
|
||||||
|
ofs << table;
|
||||||
|
}
|
||||||
|
const auto data = toml::parse("tmp.toml");
|
||||||
|
|
||||||
const auto bit = toml::get<toml::Table>(hard.at("bit#"));
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at("what?")),
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
"You don't think some user won't do that?");
|
}
|
||||||
const std::vector<std::string> expected_multi_line_array{"]"};
|
{
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
|
const std::string table(
|
||||||
expected_multi_line_array);
|
"\xEF\xBB\xBF" // BOM
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss, "test_file_with_BOM_CRLF.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"\xEF\xBB\xBF" // BOM
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
);
|
||||||
|
{
|
||||||
|
// with text-mode, "\n" is converted to "\r\n" and the resulting
|
||||||
|
// value will be "\r\r\n". To avoid the additional "\r", use binary
|
||||||
|
// mode.
|
||||||
|
std::ofstream ofs("tmp.toml", std::ios_base::binary);
|
||||||
|
ofs.write(table.data(), static_cast<std::streamsize>(table.size()));
|
||||||
|
}
|
||||||
|
const auto data = toml::parse("tmp.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\""
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\""
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file_CRLF.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\" # comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\" # comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\" \t"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file_ws.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\" \t"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_file_without_newline_at_the_end_of_file_ws.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_files_end_with_comment)
|
||||||
|
{
|
||||||
|
// comment w/o newline
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"# comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"# comment\n"
|
||||||
|
"# one more comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// comment w/ newline
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"# comment\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"# comment\n"
|
||||||
|
"# one more comment\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRLF version
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"# comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"# comment\r\n"
|
||||||
|
"# one more comment"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"# comment\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"# comment\r\n"
|
||||||
|
"# one more comment\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_comment.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// with whitespaces
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
" \n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
" \n"
|
||||||
|
" \n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"\n"
|
||||||
|
" \n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
" \n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// with whitespaces but no newline
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\n"
|
||||||
|
"[table]\n"
|
||||||
|
"key = \"value\"\n"
|
||||||
|
" "
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CRLF
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// with whitespaces
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
" \r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"\r\n"
|
||||||
|
" \r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
" \r\n"
|
||||||
|
"\r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
" \r\n"
|
||||||
|
" \r\n"
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const std::string table(
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
"[table]\r\n"
|
||||||
|
"key = \"value\"\r\n"
|
||||||
|
" "
|
||||||
|
);
|
||||||
|
std::istringstream iss(table);
|
||||||
|
const auto data = toml::parse(iss,
|
||||||
|
"test_files_end_with_newline.toml");
|
||||||
|
|
||||||
|
BOOST_TEST(toml::find<std::string>(data, "key") == "value");
|
||||||
|
BOOST_TEST(toml::find<std::string>(toml::find(data, "table"), "key") == "value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,20 +32,20 @@ BOOST_AUTO_TEST_CASE(test_fractional)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_fractional_value)
|
BOOST_AUTO_TEST_CASE(test_fractional_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1.0", value( 1.0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1.0", value( 1.0));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.1", value( 0.1));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0.1", value( 0.1));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.001", value( 0.001));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0.001", value( 0.001));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0.100", value( 0.1));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0.100", value( 0.1));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.14", value( 3.14));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+3.14", value( 3.14));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.14", value(-3.14));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-3.14", value(-3.14));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "3.1415_9265_3589", value( 3.141592653589));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "3.1415_9265_3589", value( 3.141592653589));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+3.1415_9265_3589", value( 3.141592653589));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+3.1415_9265_3589", value( 3.141592653589));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-3.1415_9265_3589", value(-3.141592653589));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-3.1415_9265_3589", value(-3.141592653589));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456.789", value( 123456.789));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "123_456.789", value( 123456.789));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+123_456.789", value( 123456.789));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+123_456.789", value( 123456.789));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-123_456.789", value(-123456.789));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-123_456.789", value(-123456.789));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+0.0", value( 0.0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+0.0", value( 0.0));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0.0", value(-0.0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-0.0", value(-0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_exponential)
|
BOOST_AUTO_TEST_CASE(test_exponential)
|
||||||
@@ -72,24 +72,24 @@ BOOST_AUTO_TEST_CASE(test_exponential)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_exponential_value)
|
BOOST_AUTO_TEST_CASE(test_exponential_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1e10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e+10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1e+10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e-10", value(1e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1e-10", value(1e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+1e10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e+10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+1e+10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e-10", value(1e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+1e-10", value(1e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e10", value(-1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-1e10", value(-1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e+10", value(-1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-1e+10", value(-1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e-10", value(-1e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-1e-10", value(-1e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123e-10", value(123e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "123e-10", value(123e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1E10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E+10", value(1e10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1E+10", value(1e10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E-10", value(1e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1E-10", value(1e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123E-10", value(123e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "123E-10", value(123e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3E-10", value(123e-10));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3E-10", value(123e-10));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "+0e0", value( 0.0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+0e0", value( 0.0));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0e0", value(-0.0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-0e0", value(-0.0));
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_fe)
|
BOOST_AUTO_TEST_CASE(test_fe)
|
||||||
{
|
{
|
||||||
@@ -99,9 +99,9 @@ BOOST_AUTO_TEST_CASE(test_fe)
|
|||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(test_fe_vaule)
|
BOOST_AUTO_TEST_CASE(test_fe_vaule)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "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, "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));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_inf)
|
BOOST_AUTO_TEST_CASE(test_inf)
|
||||||
|
|||||||
@@ -13,36 +13,36 @@ using namespace detail;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_inline_table)
|
BOOST_AUTO_TEST_CASE(test_inline_table)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{}", table());
|
TOML11_TEST_PARSE_EQUAL(parse_inline_table<toml::value>, "{}", table());
|
||||||
{
|
{
|
||||||
table t;
|
table t;
|
||||||
t["foo"] = toml::value(42);
|
t["foo"] = toml::value(42);
|
||||||
t["bar"] = toml::value("baz");
|
t["bar"] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{foo = 42, bar = \"baz\"}", t);
|
TOML11_TEST_PARSE_EQUAL(parse_inline_table<toml::value>, "{foo = 42, bar = \"baz\"}", t);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
table t;
|
table t;
|
||||||
table t_sub;
|
table t_sub;
|
||||||
t_sub["name"] = toml::value("pug");
|
t_sub["name"] = toml::value("pug");
|
||||||
t["type"] = toml::value(t_sub);
|
t["type"] = toml::value(t_sub);
|
||||||
TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{type.name = \"pug\"}", t);
|
TOML11_TEST_PARSE_EQUAL(parse_inline_table<toml::value>, "{type.name = \"pug\"}", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_inline_table_value)
|
BOOST_AUTO_TEST_CASE(test_inline_table_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{}", value(table()));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "{}", value(table()));
|
||||||
{
|
{
|
||||||
table t;
|
table t;
|
||||||
t["foo"] = toml::value(42);
|
t["foo"] = toml::value(42);
|
||||||
t["bar"] = toml::value("baz");
|
t["bar"] = toml::value("baz");
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{foo = 42, bar = \"baz\"}", value(t));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "{foo = 42, bar = \"baz\"}", value(t));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
table t;
|
table t;
|
||||||
table t_sub;
|
table t_sub;
|
||||||
t_sub["name"] = toml::value("pug");
|
t_sub["name"] = toml::value("pug");
|
||||||
t["type"] = toml::value(t_sub);
|
t["type"] = toml::value(t_sub);
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{type.name = \"pug\"}", value(t));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "{type.name = \"pug\"}", value(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ BOOST_AUTO_TEST_CASE(test_decimal)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_decimal_value)
|
BOOST_AUTO_TEST_CASE(test_decimal_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1234", toml::value( 1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1234", toml::value( 1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1234", toml::value( 1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+1234", toml::value( 1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1234", toml::value( -1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-1234", toml::value( -1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0", toml::value( 0));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0", toml::value( 0));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1_2_3_4", toml::value( 1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "1_2_3_4", toml::value( 1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1_2_3_4", toml::value( +1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "+1_2_3_4", toml::value( +1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1_2_3_4", toml::value( -1234));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "-1_2_3_4", toml::value( -1234));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "123_456_789", toml::value(123456789));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "123_456_789", toml::value(123456789));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_hex)
|
BOOST_AUTO_TEST_CASE(test_hex)
|
||||||
@@ -50,15 +50,15 @@ BOOST_AUTO_TEST_CASE(test_hex)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_hex_value)
|
BOOST_AUTO_TEST_CASE(test_hex_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADBEEF", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xDEADBEEF", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdeadbeef", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xdeadbeef", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADbeef", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xDEADbeef", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEAD_BEEF", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xDEAD_BEEF", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_beef", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xdead_beef", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_BEEF", value(0xDEADBEEF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xdead_BEEF", value(0xDEADBEEF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xFF", value(0xFF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0xFF", value(0xFF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x00FF", value(0xFF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0x00FF", value(0xFF));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x0000FF", value(0xFF));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0x0000FF", value(0xFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_oct)
|
BOOST_AUTO_TEST_CASE(test_oct)
|
||||||
@@ -70,9 +70,9 @@ BOOST_AUTO_TEST_CASE(test_oct)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_oct_value)
|
BOOST_AUTO_TEST_CASE(test_oct_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o777", value(64*7+8*7+7));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0o777", value(64*7+8*7+7));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o7_7_7", value(64*7+8*7+7));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0o7_7_7", value(64*7+8*7+7));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0o007", value(7));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0o007", value(7));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_bin)
|
BOOST_AUTO_TEST_CASE(test_bin)
|
||||||
@@ -85,8 +85,8 @@ BOOST_AUTO_TEST_CASE(test_bin)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_bin_value)
|
BOOST_AUTO_TEST_CASE(test_bin_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b10000", value(16));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b10000", value(16));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b010000", value(16));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b010000", value(16));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b01_00_00", value(16));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b01_00_00", value(16));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b111111", value(63));
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>, "0b111111", value(63));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,23 +13,23 @@ using namespace detail;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_bare_key)
|
BOOST_AUTO_TEST_CASE(test_bare_key)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "barekey", std::vector<key>(1, "barekey"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "barekey", std::vector<key>(1, "barekey"));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "bare-key", std::vector<key>(1, "bare-key"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "bare-key", std::vector<key>(1, "bare-key"));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "bare_key", std::vector<key>(1, "bare_key"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "bare_key", std::vector<key>(1, "bare_key"));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "1234", std::vector<key>(1, "1234"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "1234", std::vector<key>(1, "1234"));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_quoted_key)
|
BOOST_AUTO_TEST_CASE(test_quoted_key)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "\"127.0.0.1\"", std::vector<key>(1, "127.0.0.1" ));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "\"127.0.0.1\"", std::vector<key>(1, "127.0.0.1" ));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "\"character encoding\"", std::vector<key>(1, "character encoding"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "\"character encoding\"", std::vector<key>(1, "character encoding"));
|
||||||
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", std::vector<key>(1, "\xCA\x8E\xC7\x9D\xCA\x9E"));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "\"\xCA\x8E\xC7\x9D\xCA\x9E\"", std::vector<key>(1, "\xCA\x8E\xC7\x9D\xCA\x9E"));
|
||||||
#else
|
#else
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "\"ʎǝʞ\"", std::vector<key>(1, "ʎǝʞ" ));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "\"ʎǝʞ\"", std::vector<key>(1, "ʎǝʞ" ));
|
||||||
#endif
|
#endif
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "'key2'", std::vector<key>(1, "key2" ));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "'key2'", std::vector<key>(1, "key2" ));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "'quoted \"value\"'", std::vector<key>(1, "quoted \"value\"" ));
|
TOML11_TEST_PARSE_EQUAL(parse_key, "'quoted \"value\"'", std::vector<key>(1, "quoted \"value\"" ));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_dotted_key)
|
BOOST_AUTO_TEST_CASE(test_dotted_key)
|
||||||
@@ -38,13 +38,13 @@ BOOST_AUTO_TEST_CASE(test_dotted_key)
|
|||||||
std::vector<key> keys(2);
|
std::vector<key> keys(2);
|
||||||
keys[0] = "physical";
|
keys[0] = "physical";
|
||||||
keys[1] = "color";
|
keys[1] = "color";
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "physical.color", keys);
|
TOML11_TEST_PARSE_EQUAL(parse_key, "physical.color", keys);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::vector<key> keys(2);
|
std::vector<key> keys(2);
|
||||||
keys[0] = "physical";
|
keys[0] = "physical";
|
||||||
keys[1] = "shape";
|
keys[1] = "shape";
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "physical.shape", keys);
|
TOML11_TEST_PARSE_EQUAL(parse_key, "physical.shape", keys);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::vector<key> keys(4);
|
std::vector<key> keys(4);
|
||||||
@@ -52,12 +52,12 @@ BOOST_AUTO_TEST_CASE(test_dotted_key)
|
|||||||
keys[1] = "y";
|
keys[1] = "y";
|
||||||
keys[2] = "z";
|
keys[2] = "z";
|
||||||
keys[3] = "w";
|
keys[3] = "w";
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "x.y.z.w", keys);
|
TOML11_TEST_PARSE_EQUAL(parse_key, "x.y.z.w", keys);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::vector<key> keys(2);
|
std::vector<key> keys(2);
|
||||||
keys[0] = "site";
|
keys[0] = "site";
|
||||||
keys[1] = "google.com";
|
keys[1] = "google.com";
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_key, "site.\"google.com\"", keys);
|
TOML11_TEST_PARSE_EQUAL(parse_key, "site.\"google.com\"", keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ BOOST_AUTO_TEST_CASE(test_string)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_string_value)
|
BOOST_AUTO_TEST_CASE(test_string_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"The quick brown fox jumps over the lazy dog\"",
|
"\"The quick brown fox jumps over the lazy dog\"",
|
||||||
toml::value("The quick brown fox jumps over the lazy dog", string_t::basic));
|
toml::value("The quick brown fox jumps over the lazy dog", string_t::basic));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\'The quick brown fox jumps over the lazy dog\'",
|
"\'The quick brown fox jumps over the lazy dog\'",
|
||||||
toml::value("The quick brown fox jumps over the lazy dog", string_t::literal));
|
toml::value("The quick brown fox jumps over the lazy dog", string_t::literal));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"",
|
"\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"",
|
||||||
toml::value("The quick brown fox jumps over the lazy dog", string_t::basic));
|
toml::value("The quick brown fox jumps over the lazy dog", string_t::basic));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'''The quick brown fox \njumps over the lazy dog'''",
|
"'''The quick brown fox \njumps over the lazy dog'''",
|
||||||
toml::value("The quick brown fox \njumps over the lazy dog", string_t::literal));
|
toml::value("The quick brown fox \njumps over the lazy dog", string_t::literal));
|
||||||
}
|
}
|
||||||
@@ -73,25 +73,25 @@ BOOST_AUTO_TEST_CASE(test_basic_string)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_basic_string_value)
|
BOOST_AUTO_TEST_CASE(test_basic_string_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"",
|
"\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"",
|
||||||
value("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic));
|
value("GitHub Cofounder & CEO\nLikes tater tots and beer.", string_t::basic));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"192.168.1.1\"",
|
"\"192.168.1.1\"",
|
||||||
value("192.168.1.1", string_t::basic));
|
value("192.168.1.1", string_t::basic));
|
||||||
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
#if defined(_MSC_VER) || defined(__INTEL_COMPILER)
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"\xE4\xB8\xAD\xE5\x9B\xBD\"",
|
"\"\xE4\xB8\xAD\xE5\x9B\xBD\"",
|
||||||
value("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic));
|
value("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic));
|
||||||
#else
|
#else
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"中国\"",
|
"\"中国\"",
|
||||||
value("中国", string_t::basic));
|
value("中国", string_t::basic));
|
||||||
#endif
|
#endif
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"You'll hate me after this - #\"",
|
"\"You'll hate me after this - #\"",
|
||||||
value("You'll hate me after this - #", string_t::basic));
|
value("You'll hate me after this - #", string_t::basic));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\" And when \\\"'s are in the along with # \\\"\"",
|
"\" And when \\\"'s are in the along with # \\\"\"",
|
||||||
value(" And when \"'s are in the along with # \"", string_t::basic));
|
value(" And when \"'s are in the along with # \"", string_t::basic));
|
||||||
}
|
}
|
||||||
@@ -108,10 +108,10 @@ BOOST_AUTO_TEST_CASE(test_ml_basic_string)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_ml_basic_string_value)
|
BOOST_AUTO_TEST_CASE(test_ml_basic_string_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"",
|
"\"\"\"\nThe quick brown \\\n\n fox jumps over \\\n the lazy dog.\"\"\"",
|
||||||
value("The quick brown fox jumps over the lazy dog.", string_t::basic));
|
value("The quick brown fox jumps over the lazy dog.", string_t::basic));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"",
|
"\"\"\"\\\n The quick brown \\\n\n fox jumps over \\\n the lazy dog.\\\n \"\"\"",
|
||||||
value("The quick brown fox jumps over the lazy dog.", string_t::basic));
|
value("The quick brown fox jumps over the lazy dog.", string_t::basic));
|
||||||
}
|
}
|
||||||
@@ -134,16 +134,16 @@ BOOST_AUTO_TEST_CASE(test_literal_string)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_literal_string_value)
|
BOOST_AUTO_TEST_CASE(test_literal_string_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'C:\\Users\\nodejs\\templates'",
|
"'C:\\Users\\nodejs\\templates'",
|
||||||
value("C:\\Users\\nodejs\\templates", string_t::literal));
|
value("C:\\Users\\nodejs\\templates", string_t::literal));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'\\\\ServerX\\admin$\\system32\\'",
|
"'\\\\ServerX\\admin$\\system32\\'",
|
||||||
value("\\\\ServerX\\admin$\\system32\\", string_t::literal));
|
value("\\\\ServerX\\admin$\\system32\\", string_t::literal));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'Tom \"Dubs\" Preston-Werner'",
|
"'Tom \"Dubs\" Preston-Werner'",
|
||||||
value("Tom \"Dubs\" Preston-Werner", string_t::literal));
|
value("Tom \"Dubs\" Preston-Werner", string_t::literal));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'<\\i\\c*\\s*>'",
|
"'<\\i\\c*\\s*>'",
|
||||||
value("<\\i\\c*\\s*>", string_t::literal));
|
value("<\\i\\c*\\s*>", string_t::literal));
|
||||||
}
|
}
|
||||||
@@ -160,10 +160,10 @@ BOOST_AUTO_TEST_CASE(test_ml_literal_string)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_ml_literal_string_value)
|
BOOST_AUTO_TEST_CASE(test_ml_literal_string_value)
|
||||||
{
|
{
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'''I [dw]on't need \\d{2} apples'''",
|
"'''I [dw]on't need \\d{2} apples'''",
|
||||||
value("I [dw]on't need \\d{2} apples", string_t::literal));
|
value("I [dw]on't need \\d{2} apples", string_t::literal));
|
||||||
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value,
|
TOML11_TEST_PARSE_EQUAL_VALUE(parse_value<toml::value>,
|
||||||
"'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''",
|
"'''\nThe first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n'''",
|
||||||
value("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal));
|
value("The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n", string_t::literal));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ BOOST_AUTO_TEST_CASE(test_normal_table)
|
|||||||
);
|
);
|
||||||
location<std::string> loc("test", table);
|
location<std::string> loc("test", table);
|
||||||
|
|
||||||
const auto result = toml::detail::parse_ml_table(loc);
|
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
const auto data = result.unwrap();
|
const auto data = result.unwrap();
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string >(data.at("key1")), "value");
|
BOOST_TEST(toml::get<std::string >(data.at("key1")) == "value");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(data.at("key2")), 42);
|
BOOST_TEST(toml::get<std::int64_t>(data.at("key2")) == 42);
|
||||||
BOOST_CHECK_EQUAL(toml::get<double >(data.at("key3")), 3.14);
|
BOOST_TEST(toml::get<double >(data.at("key3")) == 3.14);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_nested_table)
|
BOOST_AUTO_TEST_CASE(test_nested_table)
|
||||||
@@ -38,13 +38,13 @@ BOOST_AUTO_TEST_CASE(test_nested_table)
|
|||||||
);
|
);
|
||||||
location<std::string> loc("test", table);
|
location<std::string> loc("test", table);
|
||||||
|
|
||||||
const auto result = toml::detail::parse_ml_table(loc);
|
const auto result = toml::detail::parse_ml_table<toml::value>(loc);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
const auto data = result.unwrap();
|
const auto data = result.unwrap();
|
||||||
|
|
||||||
const auto a = toml::get<toml::table>(data.at("a"));
|
const auto a = toml::get<toml::table>(data.at("a"));
|
||||||
const auto c = toml::get<toml::table>(a.at("c"));
|
const auto c = toml::get<toml::table>(a.at("c"));
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string >(a.at("b")), "value");
|
BOOST_TEST(toml::get<std::string >(a.at("b")) == "value");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::int64_t>(c.at("d")), 42);
|
BOOST_TEST(toml::get<std::int64_t>(c.at("d")) == 42);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
|
|||||||
{
|
{
|
||||||
const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
|
const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
|
||||||
|
|
||||||
const auto the = toml::get<toml::Table>(data.at("the"));
|
const auto the = toml::find<toml::table>(data, "the");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
|
BOOST_TEST(toml::get<std::string>(the.at("test_string")) ==
|
||||||
std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x27\xE2\x84\x93\xE2\x84\x93\x20\xCE\xBB\xC3\xA1\xC6\xAD\xC3\xA8\x20\xE2\x82\xA5\xC3\xA8\x20\xC3\xA1\xC6\x92\xC6\xAD\xC3\xA8\xC5\x99\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC6\xA8\x20\x2D\x20\x23"));
|
std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x27\xE2\x84\x93\xE2\x84\x93\x20\xCE\xBB\xC3\xA1\xC6\xAD\xC3\xA8\x20\xE2\x82\xA5\xC3\xA8\x20\xC3\xA1\xC6\x92\xC6\xAD\xC3\xA8\xC5\x99\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC6\xA8\x20\x2D\x20\x23"));
|
||||||
|
|
||||||
const auto hard = toml::get<toml::Table>(the.at("hard"));
|
const auto hard = toml::get<toml::table>(the.at("hard"));
|
||||||
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
|
||||||
expected_the_hard_test_array);
|
expected_the_hard_test_array);
|
||||||
@@ -28,13 +28,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
|
|||||||
};
|
};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
|
||||||
expected_the_hard_test_array2);
|
expected_the_hard_test_array2);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
|
BOOST_TEST(toml::get<std::string>(hard.at("another_test_string")) ==
|
||||||
std::string("\xC2\xA7\xC3\xA1\xE2\x82\xA5\xC3\xA8\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xCE\xB2\xC3\xBA\xC6\xAD\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\xC3\xA1\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x20\x23"));
|
std::string("\xC2\xA7\xC3\xA1\xE2\x82\xA5\xC3\xA8\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xCE\xB2\xC3\xBA\xC6\xAD\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\xC3\xA1\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x20\x23"));
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
|
BOOST_TEST(toml::get<std::string>(hard.at("harder_test_string")) ==
|
||||||
std::string("\x20\xC3\x82\xC3\xB1\xCE\xB4\x20\xCF\x89\xCE\xBB\xC3\xA8\xC3\xB1\x20\x22\x27\xC6\xA8\x20\xC3\xA1\xC5\x99\xC3\xA8\x20\xC3\xAF\xC3\xB1\x20\xC6\xAD\xCE\xBB\xC3\xA8\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xC3\xA1\xE2\x84\x93\xC3\xB4\xC3\xB1\xCF\xB1\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\x23\x20\x22"));
|
std::string("\x20\xC3\x82\xC3\xB1\xCE\xB4\x20\xCF\x89\xCE\xBB\xC3\xA8\xC3\xB1\x20\x22\x27\xC6\xA8\x20\xC3\xA1\xC5\x99\xC3\xA8\x20\xC3\xAF\xC3\xB1\x20\xC6\xAD\xCE\xBB\xC3\xA8\x20\xC6\xA8\xC6\xAD\xC5\x99\xC3\xAF\xC3\xB1\xCF\xB1\x2C\x20\xC3\xA1\xE2\x84\x93\xC3\xB4\xC3\xB1\xCF\xB1\x20\xCF\x89\xC3\xAF\xC6\xAD\xCE\xBB\x20\x23\x20\x22"));
|
||||||
//
|
//
|
||||||
const auto bit = toml::get<toml::Table>(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23")));
|
const auto bit = toml::get<toml::table>(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23")));
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at(std::string("\xCF\x89\xCE\xBB\xC3\xA1\xC6\xAD\x3F"))),
|
BOOST_TEST(toml::get<std::string>(bit.at(std::string("\xCF\x89\xCE\xBB\xC3\xA1\xC6\xAD\x3F"))) ==
|
||||||
std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x20\xCE\xB4\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xC6\x99\x20\xC6\xA8\xC3\xB4\xE2\x82\xA5\xC3\xA8\x20\xC3\xBA\xC6\xA8\xC3\xA8\xC5\x99\x20\xCF\x89\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xCE\xB4\xC3\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD\x3F"));
|
std::string("\xC3\x9D\xC3\xB4\xC3\xBA\x20\xCE\xB4\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xC6\xAD\xCE\xBB\xC3\xAF\xC3\xB1\xC6\x99\x20\xC6\xA8\xC3\xB4\xE2\x82\xA5\xC3\xA8\x20\xC3\xBA\xC6\xA8\xC3\xA8\xC5\x99\x20\xCF\x89\xC3\xB4\xC3\xB1\x27\xC6\xAD\x20\xCE\xB4\xC3\xB4\x20\xC6\xAD\xCE\xBB\xC3\xA1\xC6\xAD\x3F"));
|
||||||
const std::vector<std::string> expected_multi_line_array{"]"};
|
const std::vector<std::string> expected_multi_line_array{"]"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
|
||||||
@@ -45,11 +45,11 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
|
|||||||
{
|
{
|
||||||
const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
|
const auto data = toml::parse("toml/tests/hard_example_unicode.toml");
|
||||||
|
|
||||||
const auto the = toml::get<toml::Table>(data.at("the"));
|
const auto the = toml::find<toml::table>(data, "the");
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(the.at("test_string")),
|
BOOST_TEST(toml::get<std::string>(the.at("test_string")) ==
|
||||||
std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #"));
|
std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #"));
|
||||||
|
|
||||||
const auto hard = toml::get<toml::Table>(the.at("hard"));
|
const auto hard = toml::get<toml::table>(the.at("hard"));
|
||||||
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
const std::vector<std::string> expected_the_hard_test_array{"] ", " # "};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array")) ==
|
||||||
expected_the_hard_test_array);
|
expected_the_hard_test_array);
|
||||||
@@ -58,13 +58,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode)
|
|||||||
std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
|
std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(hard.at("test_array2")) ==
|
||||||
expected_the_hard_test_array2);
|
expected_the_hard_test_array2);
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("another_test_string")),
|
BOOST_TEST(toml::get<std::string>(hard.at("another_test_string")) ==
|
||||||
std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
|
std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #"));
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(hard.at("harder_test_string")),
|
BOOST_TEST(toml::get<std::string>(hard.at("harder_test_string")) ==
|
||||||
std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));
|
std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \""));
|
||||||
|
|
||||||
const auto bit = toml::get<toml::Table>(hard.at(std::string(u8"βïƭ#")));
|
const auto bit = toml::get<toml::table>(hard.at(std::string(u8"βïƭ#")));
|
||||||
BOOST_CHECK_EQUAL(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))),
|
BOOST_TEST(toml::get<std::string>(bit.at(std::string(u8"ωλáƭ?"))) ==
|
||||||
std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
|
std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?"));
|
||||||
const std::vector<std::string> expected_multi_line_array{"]"};
|
const std::vector<std::string> expected_multi_line_array{"]"};
|
||||||
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
|
BOOST_CHECK(toml::get<std::vector<std::string>>(bit.at("multi_line_array")) ==
|
||||||
|
|||||||
@@ -8,49 +8,49 @@ BOOST_AUTO_TEST_CASE(test_construct)
|
|||||||
{
|
{
|
||||||
auto s = toml::ok(42);
|
auto s = toml::ok(42);
|
||||||
toml::result<int, std::string> result(s);
|
toml::result<int, std::string> result(s);
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto s = toml::ok(42);
|
const auto s = toml::ok(42);
|
||||||
toml::result<int, std::string> result(s);
|
toml::result<int, std::string> result(s);
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::ok(42));
|
toml::result<int, std::string> result(toml::ok(42));
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto f = toml::err<std::string>("foobar");
|
auto f = toml::err<std::string>("foobar");
|
||||||
toml::result<int, std::string> result(f);
|
toml::result<int, std::string> result(f);
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar");
|
BOOST_TEST(result.unwrap_err() == "foobar");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const auto f = toml::err<std::string>("foobar");
|
const auto f = toml::err<std::string>("foobar");
|
||||||
toml::result<int, std::string> result(f);
|
toml::result<int, std::string> result(f);
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar");
|
BOOST_TEST(result.unwrap_err() == "foobar");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar");
|
BOOST_TEST(result.unwrap_err() == "foobar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,54 +59,54 @@ BOOST_AUTO_TEST_CASE(test_assignment)
|
|||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
result = toml::ok(42);
|
result = toml::ok(42);
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
auto s = toml::ok(42);
|
auto s = toml::ok(42);
|
||||||
result = s;
|
result = s;
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
const auto s = toml::ok(42);
|
const auto s = toml::ok(42);
|
||||||
result = s;
|
result = s;
|
||||||
BOOST_CHECK(!!result);
|
BOOST_TEST(!!result);
|
||||||
BOOST_CHECK(result.is_ok());
|
BOOST_TEST(result.is_ok());
|
||||||
BOOST_CHECK(!result.is_err());
|
BOOST_TEST(!result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap(), 42);
|
BOOST_TEST(result.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
result = toml::err<std::string>("hoge");
|
result = toml::err<std::string>("hoge");
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge");
|
BOOST_TEST(result.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
auto f = toml::err<std::string>("hoge");
|
auto f = toml::err<std::string>("hoge");
|
||||||
result = f;
|
result = f;
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge");
|
BOOST_TEST(result.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
toml::result<int, std::string> result(toml::err<std::string>("foobar"));
|
||||||
const auto f = toml::err<std::string>("hoge");
|
const auto f = toml::err<std::string>("hoge");
|
||||||
result = f;
|
result = f;
|
||||||
BOOST_CHECK(!result);
|
BOOST_TEST(!result);
|
||||||
BOOST_CHECK(!result.is_ok());
|
BOOST_TEST(!result.is_ok());
|
||||||
BOOST_CHECK(result.is_err());
|
BOOST_TEST(result.is_err());
|
||||||
BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge");
|
BOOST_TEST(result.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,10 +119,10 @@ BOOST_AUTO_TEST_CASE(test_map)
|
|||||||
return i * 2;
|
return i * 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42 * 2);
|
BOOST_TEST(mapped.unwrap() == 42 * 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -132,10 +132,10 @@ BOOST_AUTO_TEST_CASE(test_map)
|
|||||||
return *i;
|
return *i;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42);
|
BOOST_TEST(mapped.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -144,10 +144,10 @@ BOOST_AUTO_TEST_CASE(test_map)
|
|||||||
return i * 2;
|
return i * 2;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge");
|
BOOST_TEST(mapped.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -157,10 +157,10 @@ BOOST_AUTO_TEST_CASE(test_map)
|
|||||||
return *i;
|
return *i;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge");
|
BOOST_TEST(mapped.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,10 +173,10 @@ BOOST_AUTO_TEST_CASE(test_map_err)
|
|||||||
return s + s;
|
return s + s;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42);
|
BOOST_TEST(mapped.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -186,10 +186,10 @@ BOOST_AUTO_TEST_CASE(test_map_err)
|
|||||||
return s + s;
|
return s + s;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(*(mapped.unwrap()), 42);
|
BOOST_TEST(*(mapped.unwrap()) == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -197,10 +197,10 @@ BOOST_AUTO_TEST_CASE(test_map_err)
|
|||||||
[](const std::string s) -> std::string {
|
[](const std::string s) -> std::string {
|
||||||
return s + s;
|
return s + s;
|
||||||
});
|
});
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge");
|
BOOST_TEST(mapped.unwrap_err() == "hogehoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<int, std::unique_ptr<std::string>>
|
toml::result<int, std::unique_ptr<std::string>>
|
||||||
@@ -210,10 +210,10 @@ BOOST_AUTO_TEST_CASE(test_map_err)
|
|||||||
return *p;
|
return *p;
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge");
|
BOOST_TEST(mapped.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else)
|
|||||||
return i * 2;
|
return i * 2;
|
||||||
}, 54);
|
}, 54);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, 42 * 2);
|
BOOST_TEST(mapped == 42 * 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else)
|
|||||||
return *i;
|
return *i;
|
||||||
}, 54);
|
}, 54);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, 42);
|
BOOST_TEST(mapped == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else)
|
|||||||
return i * 2;
|
return i * 2;
|
||||||
}, 54);
|
}, 54);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, 54);
|
BOOST_TEST(mapped == 54);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else)
|
|||||||
return *i;
|
return *i;
|
||||||
}, 54);
|
}, 54);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, 54);
|
BOOST_TEST(mapped == 54);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else)
|
|||||||
return i + i;
|
return i + i;
|
||||||
}, "foobar");
|
}, "foobar");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, "foobar");
|
BOOST_TEST(mapped == "foobar");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else)
|
|||||||
return i + i;
|
return i + i;
|
||||||
}, "foobar");
|
}, "foobar");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, "foobar");
|
BOOST_TEST(mapped == "foobar");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else)
|
|||||||
return i + i;
|
return i + i;
|
||||||
}, "foobar");
|
}, "foobar");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, "hogehoge");
|
BOOST_TEST(mapped == "hogehoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -297,7 +297,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else)
|
|||||||
return i + i;
|
return i + i;
|
||||||
}, "foobar");
|
}, "foobar");
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(mapped, "hogehoge");
|
BOOST_TEST(mapped == "hogehoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,10 +311,10 @@ BOOST_AUTO_TEST_CASE(test_and_then)
|
|||||||
return toml::ok(i * 2);
|
return toml::ok(i * 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42 * 2);
|
BOOST_TEST(mapped.unwrap() == 42 * 2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -324,10 +324,10 @@ BOOST_AUTO_TEST_CASE(test_and_then)
|
|||||||
return toml::ok(*i);
|
return toml::ok(*i);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42);
|
BOOST_TEST(mapped.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -336,10 +336,10 @@ BOOST_AUTO_TEST_CASE(test_and_then)
|
|||||||
return toml::ok(i * 2);
|
return toml::ok(i * 2);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge");
|
BOOST_TEST(mapped.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -349,10 +349,10 @@ BOOST_AUTO_TEST_CASE(test_and_then)
|
|||||||
return toml::ok(*i);
|
return toml::ok(*i);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge");
|
BOOST_TEST(mapped.unwrap_err() == "hoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,10 +365,10 @@ BOOST_AUTO_TEST_CASE(test_or_else)
|
|||||||
return toml::err(s + s);
|
return toml::err(s + s);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap(), 42);
|
BOOST_TEST(mapped.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -378,10 +378,10 @@ BOOST_AUTO_TEST_CASE(test_or_else)
|
|||||||
return toml::err(s + s);
|
return toml::err(s + s);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!!mapped);
|
BOOST_TEST(!!mapped);
|
||||||
BOOST_CHECK(mapped.is_ok());
|
BOOST_TEST(mapped.is_ok());
|
||||||
BOOST_CHECK(!mapped.is_err());
|
BOOST_TEST(!mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(*mapped.unwrap(), 42);
|
BOOST_TEST(*mapped.unwrap() == 42);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
const toml::result<int, std::string> result(toml::err<std::string>("hoge"));
|
||||||
@@ -390,10 +390,10 @@ BOOST_AUTO_TEST_CASE(test_or_else)
|
|||||||
return toml::err(s + s);
|
return toml::err(s + s);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge");
|
BOOST_TEST(mapped.unwrap_err() == "hogehoge");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
toml::result<std::unique_ptr<int>, std::string>
|
toml::result<std::unique_ptr<int>, std::string>
|
||||||
@@ -403,9 +403,39 @@ BOOST_AUTO_TEST_CASE(test_or_else)
|
|||||||
return toml::err(s + s);
|
return toml::err(s + s);
|
||||||
});
|
});
|
||||||
|
|
||||||
BOOST_CHECK(!mapped);
|
BOOST_TEST(!mapped);
|
||||||
BOOST_CHECK(!mapped.is_ok());
|
BOOST_TEST(!mapped.is_ok());
|
||||||
BOOST_CHECK(mapped.is_err());
|
BOOST_TEST(mapped.is_err());
|
||||||
BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge");
|
BOOST_TEST(mapped.unwrap_err() == "hogehoge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_and_or_other)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const toml::result<int, std::string> r1(toml::ok(42));
|
||||||
|
const toml::result<int, std::string> r2(toml::err<std::string>("foo"));
|
||||||
|
|
||||||
|
BOOST_TEST(r1 == r1.or_other(r2));
|
||||||
|
BOOST_TEST(r2 == r1.and_other(r2));
|
||||||
|
BOOST_TEST(42 == r1.or_other(r2).unwrap());
|
||||||
|
BOOST_TEST("foo" == r1.and_other(r2).unwrap_err());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto r1_gen = []() -> toml::result<int, std::string> {
|
||||||
|
return toml::ok(42);
|
||||||
|
};
|
||||||
|
auto r2_gen = []() -> toml::result<int, std::string> {
|
||||||
|
return toml::err<std::string>("foo");
|
||||||
|
};
|
||||||
|
const auto r3 = r1_gen();
|
||||||
|
const auto r4 = r2_gen();
|
||||||
|
|
||||||
|
BOOST_TEST(r3 == r1_gen().or_other (r2_gen()));
|
||||||
|
BOOST_TEST(r4 == r1_gen().and_other(r2_gen()));
|
||||||
|
BOOST_TEST(42 == r1_gen().or_other (r2_gen()).unwrap());
|
||||||
|
BOOST_TEST("foo" == r1_gen().and_other(r2_gen()).unwrap_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
196
tests/test_serialize_file.cpp
Normal file
196
tests/test_serialize_file.cpp
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
#define BOOST_TEST_MODULE "test_serialize_file"
|
||||||
|
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
#else
|
||||||
|
#define BOOST_TEST_NO_LIB
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
|
#endif
|
||||||
|
#include <toml.hpp>
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serialized = toml::parse("tmp1.toml");
|
||||||
|
{
|
||||||
|
auto& owner = toml::find(serialized, "owner");
|
||||||
|
auto& bio = toml::find<std::string>(owner, "bio");
|
||||||
|
const auto CR = std::find(bio.begin(), bio.end(), '\r');
|
||||||
|
if(CR != bio.end())
|
||||||
|
{
|
||||||
|
bio.erase(CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example_map_dq)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serialized = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"tmp1.toml");
|
||||||
|
{
|
||||||
|
auto& owner = toml::find(serialized, "owner");
|
||||||
|
auto& bio = toml::find<std::string>(owner, "bio");
|
||||||
|
const auto CR = std::find(bio.begin(), bio.end(), '\r');
|
||||||
|
if(CR != bio.end())
|
||||||
|
{
|
||||||
|
bio.erase(CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example_with_comment)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments>("toml/tests/example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1_com.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serialized = toml::parse<toml::preserve_comments>("tmp1_com.toml");
|
||||||
|
{
|
||||||
|
auto& owner = toml::find(serialized, "owner");
|
||||||
|
auto& bio = toml::find<std::string>(owner, "bio");
|
||||||
|
const auto CR = std::find(bio.begin(), bio.end(), '\r');
|
||||||
|
if(CR != bio.end())
|
||||||
|
{
|
||||||
|
bio.erase(CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1_com1.toml");
|
||||||
|
ofs << std::setw(80) << serialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1_com.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto serialized = toml::parse<toml::preserve_comments, std::map, std::deque>(
|
||||||
|
"tmp1_com.toml");
|
||||||
|
{
|
||||||
|
auto& owner = toml::find(serialized, "owner");
|
||||||
|
auto& bio = toml::find<std::string>(owner, "bio");
|
||||||
|
const auto CR = std::find(bio.begin(), bio.end(), '\r');
|
||||||
|
if(CR != bio.end())
|
||||||
|
{
|
||||||
|
bio.erase(CR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp1_com1.toml");
|
||||||
|
ofs << std::setw(80) << serialized;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/fruit.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp2.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse("tmp2.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit_map_dq)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/fruit.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp2.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"tmp2.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit_with_comments)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments>("toml/tests/fruit.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp2_com.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse<toml::preserve_comments>("tmp2_com.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/fruit.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp2_com.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse<toml::preserve_comments, std::map, std::deque>("tmp2_com.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hard_example)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse("toml/tests/hard_example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp3.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse("tmp3.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hard_example_map_dq)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/hard_example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp3.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse<toml::discard_comments, std::map, std::deque>(
|
||||||
|
"tmp3.toml");
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(test_hard_example_with_comment)
|
||||||
|
{
|
||||||
|
const auto data = toml::parse<toml::preserve_comments, std::map, std::deque>(
|
||||||
|
"toml/tests/hard_example.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp3_com.toml");
|
||||||
|
ofs << std::setw(80) << data;
|
||||||
|
}
|
||||||
|
const auto serialized = toml::parse<toml::preserve_comments, std::map, std::deque>(
|
||||||
|
"tmp3_com.toml");
|
||||||
|
{
|
||||||
|
std::ofstream ofs("tmp3_com1.toml");
|
||||||
|
ofs << std::setw(80) << serialized;
|
||||||
|
}
|
||||||
|
BOOST_TEST(data == serialized);
|
||||||
|
}
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
#define BOOST_TEST_MODULE "test_to_toml"
|
|
||||||
#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
#else
|
|
||||||
#define BOOST_TEST_NO_LIB
|
|
||||||
#include <boost/test/included/unit_test.hpp>
|
|
||||||
#endif
|
|
||||||
#include <toml.hpp>
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_boolean)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(true);
|
|
||||||
toml::value v2 = toml::to_toml(false);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean);
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Boolean);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::Boolean));
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::Boolean));
|
|
||||||
BOOST_CHECK(v1.is<toml::Boolean>());
|
|
||||||
BOOST_CHECK(v2.is<toml::Boolean>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Boolean>(), true);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Boolean>(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_integer)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(-42);
|
|
||||||
toml::value v2 = toml::to_toml(42u);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Integer);
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Integer);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::Integer));
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::Integer));
|
|
||||||
BOOST_CHECK(v1.is<toml::Integer>());
|
|
||||||
BOOST_CHECK(v2.is<toml::Integer>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Integer>(), -42);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Integer>(), 42u);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_float)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(3.14);
|
|
||||||
toml::value v2 = toml::to_toml(3.14f);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Float);
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Float);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::Float));
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::Float));
|
|
||||||
BOOST_CHECK(v1.is<toml::Float>());
|
|
||||||
BOOST_CHECK(v2.is<toml::Float>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Float>(), 3.14);
|
|
||||||
BOOST_CHECK_CLOSE_FRACTION(v2.cast<toml::value_t::Float>(), 3.14, 1e-2);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_string)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(std::string("foo"));
|
|
||||||
toml::value v2 = toml::to_toml(std::string("foo"), toml::string_t::literal);
|
|
||||||
toml::value v3 = toml::to_toml("foo");
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::String);
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::String);
|
|
||||||
BOOST_CHECK_EQUAL(v3.type(), toml::value_t::String);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::String));
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::String));
|
|
||||||
BOOST_CHECK(v3.is(toml::value_t::String));
|
|
||||||
BOOST_CHECK(v1.is<toml::String>());
|
|
||||||
BOOST_CHECK(v2.is<toml::String>());
|
|
||||||
BOOST_CHECK(v3.is<toml::String>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::String>(), "foo");
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::String>(), "foo");
|
|
||||||
BOOST_CHECK_EQUAL(v3.cast<toml::value_t::String>(), "foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_local_date)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(toml::local_date(2018, toml::month_t::Jan, 31));
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalDate);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::LocalDate));
|
|
||||||
BOOST_CHECK(v1.is<toml::LocalDate>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::LocalDate>(),
|
|
||||||
toml::local_date(2018, toml::month_t::Jan, 31));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_local_time)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(toml::local_time(12, 30, 45));
|
|
||||||
toml::value v2 = toml::to_toml(std::chrono::hours(12) + std::chrono::minutes(30) +
|
|
||||||
std::chrono::seconds(45));
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalTime);
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::LocalTime);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::LocalTime));
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::LocalTime));
|
|
||||||
BOOST_CHECK(v1.is<toml::LocalTime>());
|
|
||||||
BOOST_CHECK(v2.is<toml::LocalTime>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::LocalTime>(),
|
|
||||||
toml::local_time(12, 30, 45));
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::LocalTime>(),
|
|
||||||
toml::local_time(12, 30, 45));
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::LocalTime>(),
|
|
||||||
v2.cast<toml::value_t::LocalTime>());
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_local_datetime)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(toml::local_datetime(
|
|
||||||
toml::local_date(2018, toml::month_t::Jan, 31),
|
|
||||||
toml::local_time(12, 30, 45)
|
|
||||||
));
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalDatetime);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::LocalDatetime));
|
|
||||||
BOOST_CHECK(v1.is<toml::LocalDatetime>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::LocalDatetime>(),
|
|
||||||
toml::local_datetime(
|
|
||||||
toml::local_date(2018, toml::month_t::Jan, 31),
|
|
||||||
toml::local_time(12, 30, 45)));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_offset_datetime)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml(toml::offset_datetime(
|
|
||||||
toml::local_date(2018, toml::month_t::Jan, 31),
|
|
||||||
toml::local_time(12, 30, 45),
|
|
||||||
toml::time_offset(9, 0)
|
|
||||||
));
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::OffsetDatetime);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::OffsetDatetime));
|
|
||||||
BOOST_CHECK(v1.is<toml::OffsetDatetime>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::OffsetDatetime>(),
|
|
||||||
toml::offset_datetime(
|
|
||||||
toml::local_date(2018, toml::month_t::Jan, 31),
|
|
||||||
toml::local_time(12, 30, 45),
|
|
||||||
toml::time_offset(9, 0)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_array)
|
|
||||||
{
|
|
||||||
std::vector<int> v{1,2,3,4,5};
|
|
||||||
toml::value v1 = toml::to_toml(v);
|
|
||||||
toml::value v2 = toml::to_toml(6,7,8,9,0);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Array);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::Array));
|
|
||||||
BOOST_CHECK(v1.is<toml::Array>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Array);
|
|
||||||
BOOST_CHECK(v2.is(toml::value_t::Array));
|
|
||||||
BOOST_CHECK(v2.is<toml::Array>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Array>().at(0).cast<toml::value_t::Integer>(), 1);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Array>().at(1).cast<toml::value_t::Integer>(), 2);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Array>().at(2).cast<toml::value_t::Integer>(), 3);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Array>().at(3).cast<toml::value_t::Integer>(), 4);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Array>().at(4).cast<toml::value_t::Integer>(), 5);
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Array>().at(0).cast<toml::value_t::Integer>(), 6);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Array>().at(1).cast<toml::value_t::Integer>(), 7);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Array>().at(2).cast<toml::value_t::Integer>(), 8);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Array>().at(3).cast<toml::value_t::Integer>(), 9);
|
|
||||||
BOOST_CHECK_EQUAL(v2.cast<toml::value_t::Array>().at(4).cast<toml::value_t::Integer>(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_value_table)
|
|
||||||
{
|
|
||||||
toml::value v1 = toml::to_toml({{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}});
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Table);
|
|
||||||
BOOST_CHECK(v1.is(toml::value_t::Table));
|
|
||||||
BOOST_CHECK(v1.is<toml::Table>());
|
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Table>().at("foo").cast<toml::value_t::Integer>(), 42);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Table>().at("bar").cast<toml::value_t::Float>(), 3.14);
|
|
||||||
BOOST_CHECK_EQUAL(v1.cast<toml::value_t::Table>().at("baz").cast<toml::value_t::String>().str, "qux");
|
|
||||||
}
|
|
||||||
@@ -37,48 +37,48 @@ typedef std::unordered_map<std::string, dummy_type> std_unordered_map_type;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_has_xxx)
|
BOOST_AUTO_TEST_CASE(test_has_xxx)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::forward_list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::forward_list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::deque<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::deque<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::vector<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::vector<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::set<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::set<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std::unordered_set<std::string>>::value);
|
BOOST_TEST(toml::detail::has_iterator<std::unordered_set<std::string>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std_array_type>::value);
|
BOOST_TEST(toml::detail::has_iterator<std_array_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std_map_type>::value);
|
BOOST_TEST(toml::detail::has_iterator<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<std_unordered_map_type>::value);
|
BOOST_TEST(toml::detail::has_iterator<std_unordered_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_iterator<dummy_container<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_iterator<dummy_container<dummy_type>>::value);
|
||||||
|
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::forward_list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::forward_list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::deque<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::deque<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::vector<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::vector<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std_array_type>::value);
|
BOOST_TEST(toml::detail::has_value_type<std_array_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::set<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::set<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std::unordered_set<std::string>>::value);
|
BOOST_TEST(toml::detail::has_value_type<std::unordered_set<std::string>>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std_map_type>::value);
|
BOOST_TEST(toml::detail::has_value_type<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<std_unordered_map_type>::value);
|
BOOST_TEST(toml::detail::has_value_type<std_unordered_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_value_type<dummy_container<dummy_type>>::value);
|
BOOST_TEST(toml::detail::has_value_type<dummy_container<dummy_type>>::value);
|
||||||
|
|
||||||
BOOST_CHECK(toml::detail::has_key_type<std_map_type>::value);
|
BOOST_TEST(toml::detail::has_key_type<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_key_type<std_unordered_map_type>::value);
|
BOOST_TEST(toml::detail::has_key_type<std_unordered_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_mapped_type<std_map_type>::value);
|
BOOST_TEST(toml::detail::has_mapped_type<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::has_mapped_type<std_unordered_map_type>::value);
|
BOOST_TEST(toml::detail::has_mapped_type<std_unordered_map_type>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_is_xxx)
|
BOOST_AUTO_TEST_CASE(test_is_xxx)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(toml::detail::is_container<std::list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<std::list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::forward_list<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<std::forward_list<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::deque<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<std::deque<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::vector<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<std::vector<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std_array_type>::value);
|
BOOST_TEST(toml::detail::is_container<std_array_type>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::set<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<std::set<dummy_type>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<std::unordered_set<std::string>>::value);
|
BOOST_TEST(toml::detail::is_container<std::unordered_set<std::string>>::value);
|
||||||
BOOST_CHECK(toml::detail::is_container<dummy_container<dummy_type>>::value);
|
BOOST_TEST(toml::detail::is_container<dummy_container<dummy_type>>::value);
|
||||||
|
|
||||||
BOOST_CHECK(!toml::detail::is_container<std_map_type>::value);
|
BOOST_TEST(!toml::detail::is_container<std_map_type>::value);
|
||||||
BOOST_CHECK(!toml::detail::is_container<std_unordered_map_type>::value);
|
BOOST_TEST(!toml::detail::is_container<std_unordered_map_type>::value);
|
||||||
|
|
||||||
BOOST_CHECK(toml::detail::is_map<std_map_type>::value);
|
BOOST_TEST(toml::detail::is_map<std_map_type>::value);
|
||||||
BOOST_CHECK(toml::detail::is_map<std_unordered_map_type>::value);
|
BOOST_TEST(toml::detail::is_map<std_unordered_map_type>::value);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,69 +14,39 @@ BOOST_AUTO_TEST_CASE(test_resize)
|
|||||||
{
|
{
|
||||||
typedef std::vector<int> resizable_type;
|
typedef std::vector<int> resizable_type;
|
||||||
typedef std::array<int,1> non_resizable_type;
|
typedef std::array<int,1> non_resizable_type;
|
||||||
BOOST_CHECK(toml::detail::has_resize_method<resizable_type>::value);
|
BOOST_TEST(toml::detail::has_resize_method<resizable_type>::value);
|
||||||
BOOST_CHECK(!toml::detail::has_resize_method<non_resizable_type>::value);
|
BOOST_TEST(!toml::detail::has_resize_method<non_resizable_type>::value);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool thrown = false;
|
|
||||||
std::vector<int> v;
|
std::vector<int> v;
|
||||||
try
|
toml::resize(v, 10);
|
||||||
{
|
BOOST_TEST(v.size() == 10u);
|
||||||
toml::resize(v, 10);
|
|
||||||
}
|
|
||||||
catch(std::exception& ex)
|
|
||||||
{
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
BOOST_CHECK(!thrown);
|
|
||||||
BOOST_CHECK_EQUAL(v.size(), 10u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool thrown = false;
|
|
||||||
std::array<int, 15> a;
|
std::array<int, 15> a;
|
||||||
try
|
toml::resize(a, 10);
|
||||||
{
|
BOOST_TEST(a.size() == 15u);
|
||||||
toml::resize(a, 10);
|
|
||||||
}
|
|
||||||
catch(std::exception& ex)
|
|
||||||
{
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
BOOST_CHECK(!thrown);
|
|
||||||
BOOST_CHECK_EQUAL(a.size(), 15u);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool thrown = false;
|
|
||||||
std::array<int, 15> a;
|
std::array<int, 15> a;
|
||||||
try
|
BOOST_CHECK_THROW(toml::resize(a, 20), std::invalid_argument);
|
||||||
{
|
|
||||||
toml::resize(a, 20);
|
|
||||||
}
|
|
||||||
catch(std::exception& ex)
|
|
||||||
{
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
BOOST_CHECK(thrown);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_concat_to_string)
|
BOOST_AUTO_TEST_CASE(test_concat_to_string)
|
||||||
{
|
{
|
||||||
const std::string cat = toml::concat_to_string("foo", "bar", 42);
|
const std::string cat = toml::concat_to_string("foo", "bar", 42);
|
||||||
BOOST_CHECK(cat == "foobar42");
|
BOOST_TEST(cat == "foobar42");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(test_from_string)
|
BOOST_AUTO_TEST_CASE(test_from_string)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
const std::string str("123");
|
const std::string str("123");
|
||||||
BOOST_CHECK_EQUAL(toml::from_string<int>(str, 0), 123);
|
BOOST_TEST(toml::from_string<int>(str, 0) == 123);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const std::string str("01");
|
const std::string str("01");
|
||||||
BOOST_CHECK_EQUAL(toml::from_string<int>(str, 0), 1);
|
BOOST_TEST(toml::from_string<int>(str, 0) == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
4
toml.hpp
4
toml.hpp
@@ -34,8 +34,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "toml/parser.hpp"
|
#include "toml/parser.hpp"
|
||||||
#include "toml/to_toml.hpp"
|
#include "toml/literal.hpp"
|
||||||
#include "toml/from_toml.hpp"
|
#include "toml/serializer.hpp"
|
||||||
#include "toml/get.hpp"
|
#include "toml/get.hpp"
|
||||||
|
|
||||||
#endif// TOML_FOR_MODERN_CPP
|
#endif// TOML_FOR_MODERN_CPP
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <array>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cassert>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
// they scans characters and returns region if it matches to the condition.
|
// they scans characters and returns region if it matches to the condition.
|
||||||
@@ -38,10 +41,12 @@ inline std::string show_char(const char c)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::array<char, 5> buf;
|
||||||
oss << std::hex << std::setfill('0') << std::setw(2) << "0x"
|
buf.fill('\0');
|
||||||
<< static_cast<int>(c);
|
const auto r = std::snprintf(
|
||||||
return oss.str();
|
buf.data(), buf.size(), "0x%02x", static_cast<int>(c) & 0xFF);
|
||||||
|
assert(r == static_cast<int>(buf.size()) - 1);
|
||||||
|
return std::string(buf.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,26 +56,24 @@ struct character
|
|||||||
static constexpr char target = C;
|
static constexpr char target = C;
|
||||||
|
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
|
|
||||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
|
|
||||||
const char c = *(loc.iter());
|
const char c = *(loc.iter());
|
||||||
if(c != target)
|
if(c != target)
|
||||||
{
|
{
|
||||||
return err(concat_to_string("expected '", show_char(target),
|
return none();
|
||||||
"' but got '", show_char(c), "'."));
|
|
||||||
}
|
}
|
||||||
++(loc.iter()); // update location
|
loc.advance(); // update location
|
||||||
|
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<Cont>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern() {return show_char(target);}
|
|
||||||
};
|
};
|
||||||
template<char C>
|
template<char C>
|
||||||
constexpr char character<C>::target;
|
constexpr char character<C>::target;
|
||||||
@@ -86,30 +89,24 @@ struct in_range
|
|||||||
static constexpr char lower = Low;
|
static constexpr char lower = Low;
|
||||||
|
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
|
|
||||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
|
|
||||||
const char c = *(loc.iter());
|
const char c = *(loc.iter());
|
||||||
if(c < lower || upper < c)
|
if(c < lower || upper < c)
|
||||||
{
|
{
|
||||||
return err(concat_to_string("expected character in range "
|
return none();
|
||||||
"[", show_char(lower), ", ", show_char(upper), "] but got ",
|
|
||||||
"'", show_char(c), "'."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++(loc.iter());
|
loc.advance();
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<Cont>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string("[",show_char(lower),"-",show_char(upper),"]");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
template<char L, char U> constexpr char in_range<L, U>::upper;
|
template<char L, char U> constexpr char in_range<L, U>::upper;
|
||||||
template<char L, char U> constexpr char in_range<L, U>::lower;
|
template<char L, char U> constexpr char in_range<L, U>::lower;
|
||||||
@@ -120,30 +117,24 @@ template<typename Combinator>
|
|||||||
struct exclude
|
struct exclude
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
|
|
||||||
if(loc.iter() == loc.end()) {return err("not sufficient characters");}
|
if(loc.iter() == loc.end()) {return none();}
|
||||||
auto first = loc.iter();
|
auto first = loc.iter();
|
||||||
|
|
||||||
auto rslt = Combinator::invoke(loc);
|
auto rslt = Combinator::invoke(loc);
|
||||||
if(rslt.is_ok())
|
if(rslt.is_ok())
|
||||||
{
|
{
|
||||||
loc.iter() = first; // rollback
|
loc.reset(first);
|
||||||
return err(concat_to_string(
|
return none();
|
||||||
"invalid pattern (", Combinator::pattern(), ") appeared ",
|
|
||||||
rslt.unwrap().str()));
|
|
||||||
}
|
}
|
||||||
loc.iter() = std::next(first);
|
loc.reset(std::next(first)); // XXX maybe loc.advance() is okay but...
|
||||||
return ok(region<Cont>(loc, first, loc.iter()));
|
return ok(region<Cont>(loc, first, loc.iter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string("^(", Combinator::pattern(), ')');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// increment `iter`, if matches. otherwise, just return empty string.
|
// increment `iter`, if matches. otherwise, just return empty string.
|
||||||
@@ -151,7 +142,8 @@ template<typename Combinator>
|
|||||||
struct maybe
|
struct maybe
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
@@ -163,11 +155,6 @@ struct maybe
|
|||||||
}
|
}
|
||||||
return ok(region<Cont>(loc));
|
return ok(region<Cont>(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string('(', Combinator::pattern(), ")?");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ... Ts>
|
template<typename ... Ts>
|
||||||
@@ -177,7 +164,8 @@ template<typename Head, typename ... Tail>
|
|||||||
struct sequence<Head, Tail...>
|
struct sequence<Head, Tail...>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
@@ -186,31 +174,26 @@ struct sequence<Head, Tail...>
|
|||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
{
|
{
|
||||||
loc.iter() = first;
|
loc.reset(first);
|
||||||
return err(rslt.unwrap_err());
|
return none();
|
||||||
}
|
}
|
||||||
return sequence<Tail...>::invoke(loc, std::move(rslt.unwrap()), first);
|
return sequence<Tail...>::invoke(loc, std::move(rslt.unwrap()), first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from the above function only, recursively.
|
// called from the above function only, recursively.
|
||||||
template<typename Cont, typename Iterator>
|
template<typename Cont, typename Iterator>
|
||||||
static result<region<Cont>, std::string>
|
static result<region<Cont>, none_t>
|
||||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
||||||
{
|
{
|
||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
{
|
{
|
||||||
loc.iter() = first;
|
loc.reset(first);
|
||||||
return err(rslt.unwrap_err());
|
return none();
|
||||||
}
|
}
|
||||||
reg += rslt.unwrap(); // concat regions
|
reg += rslt.unwrap(); // concat regions
|
||||||
return sequence<Tail...>::invoke(loc, std::move(reg), first);
|
return sequence<Tail...>::invoke(loc, std::move(reg), first);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string(Head::pattern(), sequence<Tail...>::pattern());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Head>
|
template<typename Head>
|
||||||
@@ -218,19 +201,18 @@ struct sequence<Head>
|
|||||||
{
|
{
|
||||||
// would be called from sequence<T ...>::invoke only.
|
// would be called from sequence<T ...>::invoke only.
|
||||||
template<typename Cont, typename Iterator>
|
template<typename Cont, typename Iterator>
|
||||||
static result<region<Cont>, std::string>
|
static result<region<Cont>, none_t>
|
||||||
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
invoke(location<Cont>& loc, region<Cont> reg, Iterator first)
|
||||||
{
|
{
|
||||||
const auto rslt = Head::invoke(loc);
|
const auto rslt = Head::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
{
|
{
|
||||||
loc.iter() = first;
|
loc.reset(first);
|
||||||
return err(rslt.unwrap_err());
|
return none();
|
||||||
}
|
}
|
||||||
reg += rslt.unwrap(); // concat regions
|
reg += rslt.unwrap(); // concat regions
|
||||||
return ok(reg);
|
return ok(reg);
|
||||||
}
|
}
|
||||||
static std::string pattern() {return Head::pattern();}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ... Ts>
|
template<typename ... Ts>
|
||||||
@@ -240,7 +222,8 @@ template<typename Head, typename ... Tail>
|
|||||||
struct either<Head, Tail...>
|
struct either<Head, Tail...>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
@@ -249,26 +232,18 @@ struct either<Head, Tail...>
|
|||||||
if(rslt.is_ok()) {return rslt;}
|
if(rslt.is_ok()) {return rslt;}
|
||||||
return either<Tail...>::invoke(loc);
|
return either<Tail...>::invoke(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string('(', Head::pattern(), ")|", either<Tail...>::pattern());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
template<typename Head>
|
template<typename Head>
|
||||||
struct either<Head>
|
struct either<Head>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
static_assert(std::is_same<char, typename Cont::value_type>::value,
|
||||||
"internal error: container::value_type should be `char`.");
|
"internal error: container::value_type should be `char`.");
|
||||||
return Head::invoke(loc);
|
return Head::invoke(loc);
|
||||||
}
|
}
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string('(', Head::pattern(), ')');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename N>
|
template<typename T, typename N>
|
||||||
@@ -282,7 +257,8 @@ template<typename T, std::size_t N>
|
|||||||
struct repeat<T, exactly<N>>
|
struct repeat<T, exactly<N>>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<Cont> retval(loc);
|
||||||
const auto first = loc.iter();
|
const auto first = loc.iter();
|
||||||
@@ -291,24 +267,21 @@ struct repeat<T, exactly<N>>
|
|||||||
auto rslt = T::invoke(loc);
|
auto rslt = T::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
{
|
{
|
||||||
loc.iter() = first;
|
loc.reset(first);
|
||||||
return err(rslt.unwrap_err());
|
return none();
|
||||||
}
|
}
|
||||||
retval += rslt.unwrap();
|
retval += rslt.unwrap();
|
||||||
}
|
}
|
||||||
return ok(std::move(retval));
|
return ok(std::move(retval));
|
||||||
}
|
}
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string('(', T::pattern(), "){", N, '}');
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, std::size_t N>
|
template<typename T, std::size_t N>
|
||||||
struct repeat<T, at_least<N>>
|
struct repeat<T, at_least<N>>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<Cont> retval(loc);
|
||||||
|
|
||||||
@@ -318,8 +291,8 @@ struct repeat<T, at_least<N>>
|
|||||||
auto rslt = T::invoke(loc);
|
auto rslt = T::invoke(loc);
|
||||||
if(rslt.is_err())
|
if(rslt.is_err())
|
||||||
{
|
{
|
||||||
loc.iter() = first;
|
loc.reset(first);
|
||||||
return err(rslt.unwrap_err());
|
return none();
|
||||||
}
|
}
|
||||||
retval += rslt.unwrap();
|
retval += rslt.unwrap();
|
||||||
}
|
}
|
||||||
@@ -333,17 +306,14 @@ struct repeat<T, at_least<N>>
|
|||||||
retval += rslt.unwrap();
|
retval += rslt.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static std::string pattern()
|
|
||||||
{
|
|
||||||
return concat_to_string('(',T::pattern(), "){", N, ",}");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct repeat<T, unlimited>
|
struct repeat<T, unlimited>
|
||||||
{
|
{
|
||||||
template<typename Cont>
|
template<typename Cont>
|
||||||
static result<region<Cont>, std::string> invoke(location<Cont>& loc)
|
static result<region<Cont>, none_t>
|
||||||
|
invoke(location<Cont>& loc)
|
||||||
{
|
{
|
||||||
region<Cont> retval(loc);
|
region<Cont> retval(loc);
|
||||||
while(true)
|
while(true)
|
||||||
@@ -356,7 +326,6 @@ struct repeat<T, unlimited>
|
|||||||
retval += rslt.unwrap();
|
retval += rslt.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static std::string pattern() {return concat_to_string('(', T::pattern(), ")*");}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
|
|||||||
385
toml/comments.hpp
Normal file
385
toml/comments.hpp
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_COMMENTS_HPP
|
||||||
|
#define TOML11_COMMENTS_HPP
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <iterator>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// This file provides mainly two classes, `preserve_comments` and `discard_comments`.
|
||||||
|
// Those two are a container that have the same interface as `std::vector<std::string>`
|
||||||
|
// but bahaves in the opposite way. `preserve_comments` is just the same as
|
||||||
|
// `std::vector<std::string>` and each `std::string` corresponds to a comment line.
|
||||||
|
// Conversely, `discard_comments` discards all the strings and ignores everything
|
||||||
|
// assigned in it. `discard_comments` is always empty and you will encounter an
|
||||||
|
// error whenever you access to the element.
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
struct discard_comments; // forward decl
|
||||||
|
|
||||||
|
// use it in the following way
|
||||||
|
//
|
||||||
|
// const toml::basic_value<toml::preserve_comments> data =
|
||||||
|
// toml::parse<toml::preserve_comments>("example.toml");
|
||||||
|
//
|
||||||
|
// the interface is almost the same as std::vector<std::string>.
|
||||||
|
struct preserve_comments
|
||||||
|
{
|
||||||
|
// `container_type` is not provided in discard_comments.
|
||||||
|
// do not use this inner-type in a generic code.
|
||||||
|
using container_type = std::vector<std::string>;
|
||||||
|
|
||||||
|
using size_type = container_type::size_type;
|
||||||
|
using difference_type = container_type::difference_type;
|
||||||
|
using value_type = container_type::value_type;
|
||||||
|
using reference = container_type::reference;
|
||||||
|
using const_reference = container_type::const_reference;
|
||||||
|
using pointer = container_type::pointer;
|
||||||
|
using const_pointer = container_type::const_pointer;
|
||||||
|
using iterator = container_type::iterator;
|
||||||
|
using const_iterator = container_type::const_iterator;
|
||||||
|
using reverse_iterator = container_type::reverse_iterator;
|
||||||
|
using const_reverse_iterator = container_type::const_reverse_iterator;
|
||||||
|
|
||||||
|
preserve_comments() = default;
|
||||||
|
~preserve_comments() = default;
|
||||||
|
preserve_comments(preserve_comments const&) = default;
|
||||||
|
preserve_comments(preserve_comments &&) = default;
|
||||||
|
preserve_comments& operator=(preserve_comments const&) = default;
|
||||||
|
preserve_comments& operator=(preserve_comments &&) = default;
|
||||||
|
|
||||||
|
explicit preserve_comments(const std::vector<std::string>& c): comments(c){}
|
||||||
|
explicit preserve_comments(std::vector<std::string>&& c)
|
||||||
|
: comments(std::move(c))
|
||||||
|
{}
|
||||||
|
preserve_comments& operator=(const std::vector<std::string>& c)
|
||||||
|
{
|
||||||
|
comments = c;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
preserve_comments& operator=(std::vector<std::string>&& c)
|
||||||
|
{
|
||||||
|
comments = std::move(c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit preserve_comments(const discard_comments&) {}
|
||||||
|
|
||||||
|
explicit preserve_comments(size_type n): comments(n) {}
|
||||||
|
preserve_comments(size_type n, const std::string& x): comments(n, x) {}
|
||||||
|
preserve_comments(std::initializer_list<std::string> x): comments(x) {}
|
||||||
|
template<typename InputIterator>
|
||||||
|
preserve_comments(InputIterator first, InputIterator last)
|
||||||
|
: comments(first, last)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename InputIterator>
|
||||||
|
void assign(InputIterator first, InputIterator last) {comments.assign(first, last);}
|
||||||
|
void assign(std::initializer_list<std::string> ini) {comments.assign(ini);}
|
||||||
|
void assign(size_type n, const std::string& val) {comments.assign(n, val);}
|
||||||
|
|
||||||
|
iterator insert(const_iterator p, const std::string& x)
|
||||||
|
{
|
||||||
|
return comments.insert(p, x);
|
||||||
|
}
|
||||||
|
iterator insert(const_iterator p, std::string&& x)
|
||||||
|
{
|
||||||
|
return comments.insert(p, std::move(x));
|
||||||
|
}
|
||||||
|
iterator insert(const_iterator p, size_type n, const std::string& x)
|
||||||
|
{
|
||||||
|
return comments.insert(p, n, x);
|
||||||
|
}
|
||||||
|
template<typename InputIterator>
|
||||||
|
iterator insert(const_iterator p, InputIterator first, InputIterator last)
|
||||||
|
{
|
||||||
|
return comments.insert(p, first, last);
|
||||||
|
}
|
||||||
|
iterator insert(const_iterator p, std::initializer_list<std::string> ini)
|
||||||
|
{
|
||||||
|
return comments.insert(p, ini);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ... Ts>
|
||||||
|
iterator emplace(const_iterator p, Ts&& ... args)
|
||||||
|
{
|
||||||
|
return comments.emplace(p, std::forward<Ts>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator erase(const_iterator pos) {return comments.erase(pos);}
|
||||||
|
iterator erase(const_iterator first, const_iterator last)
|
||||||
|
{
|
||||||
|
return comments.erase(first, last);
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(preserve_comments& other) {comments.swap(other.comments);}
|
||||||
|
|
||||||
|
void push_back(const std::string& v) {comments.push_back(v);}
|
||||||
|
void push_back(std::string&& v) {comments.push_back(std::move(v));}
|
||||||
|
void pop_back() {comments.pop_back();}
|
||||||
|
|
||||||
|
template<typename ... Ts>
|
||||||
|
void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward<Ts>(args)...);}
|
||||||
|
|
||||||
|
void clear() {comments.clear();}
|
||||||
|
|
||||||
|
size_type size() const noexcept {return comments.size();}
|
||||||
|
size_type max_size() const noexcept {return comments.max_size();}
|
||||||
|
size_type capacity() const noexcept {return comments.capacity();}
|
||||||
|
bool empty() const noexcept {return comments.empty();}
|
||||||
|
|
||||||
|
void reserve(size_type n) {comments.reserve(n);}
|
||||||
|
void resize(size_type n) {comments.resize(n);}
|
||||||
|
void resize(size_type n, const std::string& c) {comments.resize(n, c);}
|
||||||
|
void shrink_to_fit() {comments.shrink_to_fit();}
|
||||||
|
|
||||||
|
reference operator[](const size_type n) noexcept {return comments[n];}
|
||||||
|
const_reference operator[](const size_type n) const noexcept {return comments[n];}
|
||||||
|
reference at(const size_type n) {return comments.at(n);}
|
||||||
|
const_reference at(const size_type n) const {return comments.at(n);}
|
||||||
|
reference front() noexcept {return comments.front();}
|
||||||
|
const_reference front() const noexcept {return comments.front();}
|
||||||
|
reference back() noexcept {return comments.back();}
|
||||||
|
const_reference back() const noexcept {return comments.back();}
|
||||||
|
|
||||||
|
pointer data() noexcept {return comments.data();}
|
||||||
|
const_pointer data() const noexcept {return comments.data();}
|
||||||
|
|
||||||
|
iterator begin() noexcept {return comments.begin();}
|
||||||
|
iterator end() noexcept {return comments.end();}
|
||||||
|
const_iterator begin() const noexcept {return comments.begin();}
|
||||||
|
const_iterator end() const noexcept {return comments.end();}
|
||||||
|
const_iterator cbegin() const noexcept {return comments.cbegin();}
|
||||||
|
const_iterator cend() const noexcept {return comments.cend();}
|
||||||
|
|
||||||
|
reverse_iterator rbegin() noexcept {return comments.rbegin();}
|
||||||
|
reverse_iterator rend() noexcept {return comments.rend();}
|
||||||
|
const_reverse_iterator rbegin() const noexcept {return comments.rbegin();}
|
||||||
|
const_reverse_iterator rend() const noexcept {return comments.rend();}
|
||||||
|
const_reverse_iterator crbegin() const noexcept {return comments.crbegin();}
|
||||||
|
const_reverse_iterator crend() const noexcept {return comments.crend();}
|
||||||
|
|
||||||
|
friend bool operator==(const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
friend bool operator!=(const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
friend bool operator< (const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
friend bool operator<=(const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
friend bool operator> (const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
friend bool operator>=(const preserve_comments& lhs, const preserve_comments& rhs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
container_type comments;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments == rhs.comments;}
|
||||||
|
inline bool operator!=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments != rhs.comments;}
|
||||||
|
inline bool operator< (const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments < rhs.comments;}
|
||||||
|
inline bool operator<=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments <= rhs.comments;}
|
||||||
|
inline bool operator> (const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments > rhs.comments;}
|
||||||
|
inline bool operator>=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments >= rhs.comments;}
|
||||||
|
|
||||||
|
inline void swap(preserve_comments& lhs, preserve_comments& rhs)
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
// To provide the same interface with `preserve_comments`, `discard_comments`
|
||||||
|
// should have an iterator. But it does not contain anything, so we need to
|
||||||
|
// add an iterator that points nothing.
|
||||||
|
//
|
||||||
|
// It always points null, so DO NOT unwrap this iterator. It always crashes
|
||||||
|
// your program.
|
||||||
|
template<typename T, bool is_const>
|
||||||
|
struct empty_iterator
|
||||||
|
{
|
||||||
|
using value_type = T;
|
||||||
|
using reference_type = typename std::conditional<is_const, T const&, T&>::type;
|
||||||
|
using pointer_type = typename std::conditional<is_const, T const*, T*>::type;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using iterator_category = std::random_access_iterator_tag;
|
||||||
|
|
||||||
|
empty_iterator() = default;
|
||||||
|
~empty_iterator() = default;
|
||||||
|
empty_iterator(empty_iterator const&) = default;
|
||||||
|
empty_iterator(empty_iterator &&) = default;
|
||||||
|
empty_iterator& operator=(empty_iterator const&) = default;
|
||||||
|
empty_iterator& operator=(empty_iterator &&) = default;
|
||||||
|
|
||||||
|
// DO NOT call these operators.
|
||||||
|
reference_type operator*() const noexcept {std::terminate();}
|
||||||
|
pointer_type operator->() const noexcept {return nullptr;}
|
||||||
|
reference_type operator[](difference_type) const noexcept {return this->operator*();}
|
||||||
|
|
||||||
|
// These operators do nothing.
|
||||||
|
empty_iterator& operator++() noexcept {return *this;}
|
||||||
|
empty_iterator operator++(int) noexcept {return *this;}
|
||||||
|
empty_iterator& operator--() noexcept {return *this;}
|
||||||
|
empty_iterator operator--(int) noexcept {return *this;}
|
||||||
|
|
||||||
|
empty_iterator& operator+=(difference_type) noexcept {return *this;}
|
||||||
|
empty_iterator& operator-=(difference_type) noexcept {return *this;}
|
||||||
|
|
||||||
|
empty_iterator operator+(difference_type) const noexcept {return *this;}
|
||||||
|
empty_iterator operator-(difference_type) const noexcept {return *this;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator==(const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return true;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator!=(const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return false;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator< (const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return false;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator<=(const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return true;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator> (const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return false;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
bool operator>=(const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return true;}
|
||||||
|
|
||||||
|
template<typename T, bool C>
|
||||||
|
typename empty_iterator<T, C>::difference_type
|
||||||
|
operator-(const empty_iterator<T, C>&, const empty_iterator<T, C>&) noexcept {return 0;}
|
||||||
|
|
||||||
|
template<typename T, bool C>
|
||||||
|
empty_iterator<T, C>
|
||||||
|
operator+(typename empty_iterator<T, C>::difference_type, const empty_iterator<T, C>& rhs) noexcept {return rhs;}
|
||||||
|
template<typename T, bool C>
|
||||||
|
empty_iterator<T, C>
|
||||||
|
operator+(const empty_iterator<T, C>& lhs, typename empty_iterator<T, C>::difference_type) noexcept {return lhs;}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
// The default comment type. It discards all the comments. It requires only one
|
||||||
|
// byte to contain, so the memory footprint is smaller than preserve_comments.
|
||||||
|
//
|
||||||
|
// It just ignores `push_back`, `insert`, `erase`, and any other modifications.
|
||||||
|
// IT always returns size() == 0, the iterator taken by `begin()` is always the
|
||||||
|
// same as that of `end()`, and accessing through `operator[]` or iterators
|
||||||
|
// always causes a segmentation fault. DO NOT access to the element of this.
|
||||||
|
//
|
||||||
|
// Why this is chose as the default type is because the last version (2.x.y)
|
||||||
|
// does not contain any comments in a value. To minimize the impact on the
|
||||||
|
// efficiency, this is choosed as a default.
|
||||||
|
//
|
||||||
|
// To reduce the memory footprint, later we can try empty base optimization (EBO).
|
||||||
|
struct discard_comments
|
||||||
|
{
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = std::string;
|
||||||
|
using reference = std::string&;
|
||||||
|
using const_reference = std::string const&;
|
||||||
|
using pointer = std::string*;
|
||||||
|
using const_pointer = std::string const*;
|
||||||
|
using iterator = detail::empty_iterator<std::string, false>;
|
||||||
|
using const_iterator = detail::empty_iterator<std::string, true>;
|
||||||
|
using reverse_iterator = detail::empty_iterator<std::string, false>;
|
||||||
|
using const_reverse_iterator = detail::empty_iterator<std::string, true>;
|
||||||
|
|
||||||
|
discard_comments() = default;
|
||||||
|
~discard_comments() = default;
|
||||||
|
discard_comments(discard_comments const&) = default;
|
||||||
|
discard_comments(discard_comments &&) = default;
|
||||||
|
discard_comments& operator=(discard_comments const&) = default;
|
||||||
|
discard_comments& operator=(discard_comments &&) = default;
|
||||||
|
|
||||||
|
explicit discard_comments(const std::vector<std::string>&) noexcept {}
|
||||||
|
explicit discard_comments(std::vector<std::string>&&) noexcept {}
|
||||||
|
discard_comments& operator=(const std::vector<std::string>&) noexcept {return *this;}
|
||||||
|
discard_comments& operator=(std::vector<std::string>&&) noexcept {return *this;}
|
||||||
|
|
||||||
|
explicit discard_comments(const preserve_comments&) noexcept {}
|
||||||
|
|
||||||
|
explicit discard_comments(size_type) noexcept {}
|
||||||
|
discard_comments(size_type, const std::string&) noexcept {}
|
||||||
|
discard_comments(std::initializer_list<std::string>) noexcept {}
|
||||||
|
template<typename InputIterator>
|
||||||
|
discard_comments(InputIterator, InputIterator) noexcept {}
|
||||||
|
|
||||||
|
template<typename InputIterator>
|
||||||
|
void assign(InputIterator, InputIterator) noexcept {}
|
||||||
|
void assign(std::initializer_list<std::string>) noexcept {}
|
||||||
|
void assign(size_type, const std::string&) noexcept {}
|
||||||
|
|
||||||
|
iterator insert(const_iterator, const std::string&) {return iterator{};}
|
||||||
|
iterator insert(const_iterator, std::string&&) {return iterator{};}
|
||||||
|
iterator insert(const_iterator, size_type, const std::string&) {return iterator{};}
|
||||||
|
template<typename InputIterator>
|
||||||
|
iterator insert(const_iterator, InputIterator, InputIterator) {return iterator{};}
|
||||||
|
iterator insert(const_iterator, std::initializer_list<std::string>) {return iterator{};}
|
||||||
|
|
||||||
|
template<typename ... Ts>
|
||||||
|
iterator emplace(const_iterator, Ts&& ...) {return iterator{};}
|
||||||
|
iterator erase(const_iterator) {return iterator{};}
|
||||||
|
iterator erase(const_iterator, const_iterator) {return iterator{};}
|
||||||
|
|
||||||
|
void swap(discard_comments&) {return;}
|
||||||
|
|
||||||
|
void push_back(const std::string&) {return;}
|
||||||
|
void push_back(std::string&& ) {return;}
|
||||||
|
void pop_back() {return;}
|
||||||
|
|
||||||
|
template<typename ... Ts>
|
||||||
|
void emplace_back(Ts&& ...) {return;}
|
||||||
|
|
||||||
|
void clear() {return;}
|
||||||
|
|
||||||
|
size_type size() const noexcept {return 0;}
|
||||||
|
size_type max_size() const noexcept {return 0;}
|
||||||
|
size_type capacity() const noexcept {return 0;}
|
||||||
|
bool empty() const noexcept {return true;}
|
||||||
|
|
||||||
|
void reserve(size_type) {return;}
|
||||||
|
void resize(size_type) {return;}
|
||||||
|
void resize(size_type, const std::string&) {return;}
|
||||||
|
void shrink_to_fit() {return;}
|
||||||
|
|
||||||
|
// DO NOT access to the element of this container. This container is always
|
||||||
|
// empty, so accessing through operator[], front/back, data causes address
|
||||||
|
// error.
|
||||||
|
|
||||||
|
reference operator[](const size_type) noexcept {return *data();}
|
||||||
|
const_reference operator[](const size_type) const noexcept {return *data();}
|
||||||
|
reference at(const size_type) {throw std::out_of_range("toml::discard_comment is always empty.");}
|
||||||
|
const_reference at(const size_type) const {throw std::out_of_range("toml::discard_comment is always empty.");}
|
||||||
|
reference front() noexcept {return *data();}
|
||||||
|
const_reference front() const noexcept {return *data();}
|
||||||
|
reference back() noexcept {return *data();}
|
||||||
|
const_reference back() const noexcept {return *data();}
|
||||||
|
|
||||||
|
pointer data() noexcept {return nullptr;}
|
||||||
|
const_pointer data() const noexcept {return nullptr;}
|
||||||
|
|
||||||
|
iterator begin() noexcept {return iterator{};}
|
||||||
|
iterator end() noexcept {return iterator{};}
|
||||||
|
const_iterator begin() const noexcept {return const_iterator{};}
|
||||||
|
const_iterator end() const noexcept {return const_iterator{};}
|
||||||
|
const_iterator cbegin() const noexcept {return const_iterator{};}
|
||||||
|
const_iterator cend() const noexcept {return const_iterator{};}
|
||||||
|
|
||||||
|
reverse_iterator rbegin() noexcept {return iterator{};}
|
||||||
|
reverse_iterator rend() noexcept {return iterator{};}
|
||||||
|
const_reverse_iterator rbegin() const noexcept {return const_iterator{};}
|
||||||
|
const_reverse_iterator rend() const noexcept {return const_iterator{};}
|
||||||
|
const_reverse_iterator crbegin() const noexcept {return const_iterator{};}
|
||||||
|
const_reverse_iterator crend() const noexcept {return const_iterator{};}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const discard_comments&, const discard_comments&) noexcept {return true;}
|
||||||
|
inline bool operator!=(const discard_comments&, const discard_comments&) noexcept {return false;}
|
||||||
|
inline bool operator< (const discard_comments&, const discard_comments&) noexcept {return false;}
|
||||||
|
inline bool operator<=(const discard_comments&, const discard_comments&) noexcept {return true;}
|
||||||
|
inline bool operator> (const discard_comments&, const discard_comments&) noexcept {return false;}
|
||||||
|
inline bool operator>=(const discard_comments&, const discard_comments&) noexcept {return true;}
|
||||||
|
|
||||||
|
inline void swap(const discard_comments&, const discard_comments&) noexcept {return;}
|
||||||
|
|
||||||
|
} // toml11
|
||||||
|
#endif// TOML11_COMMENTS_HPP
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_DATETIME
|
#ifndef TOML11_DATETIME_HPP
|
||||||
#define TOML11_DATETIME
|
#define TOML11_DATETIME_HPP
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <array>
|
#include <array>
|
||||||
@@ -14,7 +14,39 @@
|
|||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class month_t : std::int8_t
|
// To avoid non-threadsafe std::localtime. In C11 (not C++11!), localtime_s is
|
||||||
|
// provided in the absolutely same purpose, but C++11 is actually not compatible
|
||||||
|
// with C11. We need to dispatch the function depending on the OS.
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
// TODO: find more sophisticated way to handle this
|
||||||
|
#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE
|
||||||
|
inline std::tm localtime_s(const std::time_t* src)
|
||||||
|
{
|
||||||
|
std::tm dst;
|
||||||
|
const auto result = ::localtime_r(src, &dst);
|
||||||
|
if (!result) { throw std::runtime_error("localtime_r failed."); }
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
#elif _MSC_VER
|
||||||
|
inline std::tm localtime_s(const std::time_t* src)
|
||||||
|
{
|
||||||
|
std::tm dst;
|
||||||
|
const auto result = ::localtime_s(&dst, src);
|
||||||
|
if (result) { throw std::runtime_error("localtime_s failed."); }
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline std::tm localtime_s(const std::time_t* src)
|
||||||
|
{
|
||||||
|
const auto result = std::localtime(src);
|
||||||
|
if (!result) { throw std::runtime_error("localtime failed."); }
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
enum class month_t : std::uint8_t
|
||||||
{
|
{
|
||||||
Jan = 0,
|
Jan = 0,
|
||||||
Feb = 1,
|
Feb = 1,
|
||||||
@@ -50,10 +82,8 @@ struct local_date
|
|||||||
|
|
||||||
explicit local_date(const std::chrono::system_clock::time_point& tp)
|
explicit local_date(const std::chrono::system_clock::time_point& tp)
|
||||||
{
|
{
|
||||||
const auto t = std::chrono::system_clock::to_time_t(tp);
|
const auto t = std::chrono::system_clock::to_time_t(tp);
|
||||||
const auto tmp = std::localtime(&t); //XXX: not threadsafe!
|
const auto time = detail::localtime_s(&t);
|
||||||
assert(tmp); // if std::localtime fails, tmp is nullptr
|
|
||||||
const std::tm time = *tmp;
|
|
||||||
*this = local_date(time);
|
*this = local_date(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,9 +98,9 @@ struct local_date
|
|||||||
t.tm_sec = 0;
|
t.tm_sec = 0;
|
||||||
t.tm_min = 0;
|
t.tm_min = 0;
|
||||||
t.tm_hour = 0;
|
t.tm_hour = 0;
|
||||||
t.tm_mday = this->day;
|
t.tm_mday = static_cast<int>(this->day);
|
||||||
t.tm_mon = this->month;
|
t.tm_mon = static_cast<int>(this->month);
|
||||||
t.tm_year = this->year - 1900;
|
t.tm_year = static_cast<int>(this->year) - 1900;
|
||||||
t.tm_wday = 0; // the value will be ignored
|
t.tm_wday = 0; // the value will be ignored
|
||||||
t.tm_yday = 0; // the value will be ignored
|
t.tm_yday = 0; // the value will be ignored
|
||||||
t.tm_isdst = -1;
|
t.tm_isdst = -1;
|
||||||
@@ -158,22 +188,22 @@ struct local_time
|
|||||||
explicit local_time(const std::chrono::duration<Rep, Period>& t)
|
explicit local_time(const std::chrono::duration<Rep, Period>& t)
|
||||||
{
|
{
|
||||||
const auto h = std::chrono::duration_cast<std::chrono::hours>(t);
|
const auto h = std::chrono::duration_cast<std::chrono::hours>(t);
|
||||||
this->hour = h.count();
|
this->hour = static_cast<std::uint8_t>(h.count());
|
||||||
const auto t2 = t - h;
|
const auto t2 = t - h;
|
||||||
const auto m = std::chrono::duration_cast<std::chrono::minutes>(t2);
|
const auto m = std::chrono::duration_cast<std::chrono::minutes>(t2);
|
||||||
this->minute = m.count();
|
this->minute = static_cast<std::uint8_t>(m.count());
|
||||||
const auto t3 = t2 - m;
|
const auto t3 = t2 - m;
|
||||||
const auto s = std::chrono::duration_cast<std::chrono::seconds>(t3);
|
const auto s = std::chrono::duration_cast<std::chrono::seconds>(t3);
|
||||||
this->second = s.count();
|
this->second = static_cast<std::uint8_t>(s.count());
|
||||||
const auto t4 = t3 - s;
|
const auto t4 = t3 - s;
|
||||||
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t4);
|
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(t4);
|
||||||
this->millisecond = ms.count();
|
this->millisecond = static_cast<std::uint16_t>(ms.count());
|
||||||
const auto t5 = t4 - ms;
|
const auto t5 = t4 - ms;
|
||||||
const auto us = std::chrono::duration_cast<std::chrono::microseconds>(t5);
|
const auto us = std::chrono::duration_cast<std::chrono::microseconds>(t5);
|
||||||
this->microsecond = us.count();
|
this->microsecond = static_cast<std::uint16_t>(us.count());
|
||||||
const auto t6 = t5 - us;
|
const auto t6 = t5 - us;
|
||||||
const auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t6);
|
const auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(t6);
|
||||||
this->nanosecond = ns.count();
|
this->nanosecond = static_cast<std::uint16_t>(ns.count());
|
||||||
}
|
}
|
||||||
|
|
||||||
operator std::chrono::nanoseconds() const
|
operator std::chrono::nanoseconds() const
|
||||||
@@ -304,17 +334,10 @@ operator<<(std::basic_ostream<charT, traits>& os, const time_offset& offset)
|
|||||||
os << 'Z';
|
os << 'Z';
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
if(static_cast<int>(offset.hour) * static_cast<int>(offset.minute) < 0)
|
int minute = static_cast<int>(offset.hour) * 60 + offset.minute;
|
||||||
{
|
if(minute < 0){os << '-'; minute = std::abs(minute);} else {os << '+';}
|
||||||
const int min = static_cast<int>(offset.hour) * 60 + offset.minute;
|
os << std::setfill('0') << std::setw(2) << minute / 60 << ':';
|
||||||
if(min < 0){os << '-';} else {os << '+';}
|
os << std::setfill('0') << std::setw(2) << minute % 60;
|
||||||
os << std::setfill('0') << std::setw(2) << min / 60 << ':';
|
|
||||||
os << std::setfill('0') << std::setw(2) << min % 60;
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
if(offset.hour < 0){os << '-';} else {os << '+';}
|
|
||||||
os << std::setfill('0') << std::setw(2) << static_cast<int>(offset.hour) << ':';
|
|
||||||
os << std::setfill('0') << std::setw(2) << static_cast<int>(offset.minute);
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,23 +353,21 @@ struct local_datetime
|
|||||||
explicit local_datetime(const std::chrono::system_clock::time_point& tp)
|
explicit local_datetime(const std::chrono::system_clock::time_point& tp)
|
||||||
{
|
{
|
||||||
const auto t = std::chrono::system_clock::to_time_t(tp);
|
const auto t = std::chrono::system_clock::to_time_t(tp);
|
||||||
const auto tmp = std::localtime(&t); //XXX: not threadsafe!
|
std::tm ltime = detail::localtime_s(&t);
|
||||||
assert(tmp); // if std::localtime fails, tmp is nullptr
|
|
||||||
|
|
||||||
std::tm time = *tmp;
|
this->date = local_date(ltime);
|
||||||
this->date = local_date(time);
|
this->time = local_time(ltime);
|
||||||
this->time = local_time(time);
|
|
||||||
|
|
||||||
// std::tm lacks subsecond information, so diff between tp and tm
|
// std::tm lacks subsecond information, so diff between tp and tm
|
||||||
// can be used to get millisecond & microsecond information.
|
// can be used to get millisecond & microsecond information.
|
||||||
const auto t_diff = tp -
|
const auto t_diff = tp -
|
||||||
std::chrono::system_clock::from_time_t(std::mktime(&time));
|
std::chrono::system_clock::from_time_t(std::mktime(<ime));
|
||||||
this->time.millisecond = std::chrono::duration_cast<
|
this->time.millisecond = static_cast<std::uint16_t>(
|
||||||
std::chrono::milliseconds>(t_diff).count();
|
std::chrono::duration_cast<std::chrono::milliseconds>(t_diff).count());
|
||||||
this->time.microsecond = std::chrono::duration_cast<
|
this->time.microsecond = static_cast<std::uint16_t>(
|
||||||
std::chrono::microseconds>(t_diff).count();
|
std::chrono::duration_cast<std::chrono::microseconds>(t_diff).count());
|
||||||
this->time.nanosecond = std::chrono::duration_cast<
|
this->time.nanosecond = static_cast<std::uint16_t>(
|
||||||
std::chrono::nanoseconds >(t_diff).count();
|
std::chrono::duration_cast<std::chrono::nanoseconds >(t_diff).count());
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit local_datetime(const std::time_t t)
|
explicit local_datetime(const std::time_t t)
|
||||||
@@ -482,10 +503,8 @@ struct offset_datetime
|
|||||||
static time_offset get_local_offset()
|
static time_offset get_local_offset()
|
||||||
{
|
{
|
||||||
// get current timezone
|
// get current timezone
|
||||||
const auto tmp1 = std::time(nullptr);
|
const auto tmp1 = std::time(nullptr);
|
||||||
const auto tmp2 = std::localtime(&tmp1); // XXX not threadsafe!
|
const auto t = detail::localtime_s(&tmp1);
|
||||||
assert(tmp2);
|
|
||||||
std::tm t = *tmp2;
|
|
||||||
|
|
||||||
std::array<char, 6> buf;
|
std::array<char, 6> buf;
|
||||||
const auto result = std::strftime(buf.data(), 6, "%z", &t); // +hhmm\0
|
const auto result = std::strftime(buf.data(), 6, "%z", &t); // +hhmm\0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_EXCEPTION
|
#ifndef TOML11_EXCEPTION_HPP
|
||||||
#define TOML11_EXCEPTION
|
#define TOML11_EXCEPTION_HPP
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|||||||
20
toml/from.hpp
Normal file
20
toml/from.hpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_FROM_HPP
|
||||||
|
#define TOML11_FROM_HPP
|
||||||
|
#include "traits.hpp"
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct from;
|
||||||
|
// {
|
||||||
|
// static T from_toml(const toml::value& v)
|
||||||
|
// {
|
||||||
|
// // User-defined conversions ...
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
} // toml
|
||||||
|
#endif // TOML11_FROM_HPP
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
// Copyright Toru Niina 2017.
|
|
||||||
// Distributed under the MIT License.
|
|
||||||
#ifndef TOML11_FROM_TOML
|
|
||||||
#define TOML11_FROM_TOML
|
|
||||||
#include "get.hpp"
|
|
||||||
|
|
||||||
namespace toml
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void from_toml(T& x, const toml::value& v)
|
|
||||||
{
|
|
||||||
x = toml::get<typename std::remove_reference<T>::type>(v);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
constexpr toml::value_t determine_castable_type()
|
|
||||||
{
|
|
||||||
return check_type<T>() != toml::value_t::Unknown ? check_type<T>() :
|
|
||||||
toml::detail::is_map<T>::value ? toml::value_t::Table :
|
|
||||||
toml::detail::is_container<T>::value ? toml::value_t::Array :
|
|
||||||
toml::value_t::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t N, typename ... Ts>
|
|
||||||
struct from_toml_tie_impl
|
|
||||||
{
|
|
||||||
constexpr static std::size_t index = sizeof...(Ts) - N;
|
|
||||||
constexpr static toml::value_t type_index =
|
|
||||||
determine_castable_type<
|
|
||||||
typename std::tuple_element<index, std::tuple<Ts...>>::type>();
|
|
||||||
|
|
||||||
static void invoke(std::tuple<Ts& ...> tie, const toml::value& v)
|
|
||||||
{
|
|
||||||
// static_cast is needed because with intel c++ compiler, operator==
|
|
||||||
// is only defined when the two types are strictly equal, and type_index
|
|
||||||
// is const toml::value_t, while v.type() is toml::value_t.
|
|
||||||
if(static_cast<toml::value_t>(type_index) == v.type())
|
|
||||||
{
|
|
||||||
from_toml(std::get<index>(tie), v);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return from_toml_tie_impl<N-1, Ts...>::invoke(tie, v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename ... Ts>
|
|
||||||
struct from_toml_tie_impl<0, Ts...>
|
|
||||||
{
|
|
||||||
static void invoke(std::tuple<Ts& ...> tie, const toml::value& v)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
template<typename ... Ts>
|
|
||||||
void from_toml(std::tuple<Ts& ...> tie, const toml::value& v)
|
|
||||||
{
|
|
||||||
detail::from_toml_tie_impl<sizeof...(Ts), Ts...>::invoke(tie, v);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // toml
|
|
||||||
#endif // TOML11_FROM_TOML
|
|
||||||
1007
toml/get.hpp
1007
toml/get.hpp
File diff suppressed because it is too large
Load Diff
20
toml/into.hpp
Normal file
20
toml/into.hpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_INTO_HPP
|
||||||
|
#define TOML11_INTO_HPP
|
||||||
|
#include "traits.hpp"
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct into;
|
||||||
|
// {
|
||||||
|
// static toml::value into_toml(const T& user_defined_type)
|
||||||
|
// {
|
||||||
|
// // User-defined conversions ...
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
} // toml
|
||||||
|
#endif // TOML11_INTO_HPP
|
||||||
@@ -124,9 +124,9 @@ using lex_escape_unicode_short = sequence<character<'u'>,
|
|||||||
using lex_escape_unicode_long = sequence<character<'U'>,
|
using lex_escape_unicode_long = sequence<character<'U'>,
|
||||||
repeat<lex_hex_dig, exactly<8>>>;
|
repeat<lex_hex_dig, exactly<8>>>;
|
||||||
using lex_escape_seq_char = either<character<'"'>, character<'\\'>,
|
using lex_escape_seq_char = either<character<'"'>, character<'\\'>,
|
||||||
character<'/'>, character<'b'>,
|
character<'b'>, character<'f'>,
|
||||||
character<'f'>, character<'n'>,
|
character<'n'>, character<'r'>,
|
||||||
character<'r'>, character<'t'>,
|
character<'t'>,
|
||||||
lex_escape_unicode_short,
|
lex_escape_unicode_short,
|
||||||
lex_escape_unicode_long
|
lex_escape_unicode_long
|
||||||
>;
|
>;
|
||||||
|
|||||||
86
toml/literal.hpp
Normal file
86
toml/literal.hpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_LITERAL_HPP
|
||||||
|
#define TOML11_LITERAL_HPP
|
||||||
|
#include "parser.hpp"
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
inline namespace literals
|
||||||
|
{
|
||||||
|
inline namespace toml_literals
|
||||||
|
{
|
||||||
|
|
||||||
|
inline ::toml::value operator"" _toml(const char* str, std::size_t len)
|
||||||
|
{
|
||||||
|
::toml::detail::location<std::vector<char>>
|
||||||
|
loc(/* filename = */ std::string("TOML literal encoded in a C++ code"),
|
||||||
|
/* contents = */ std::vector<char>(str, str + len));
|
||||||
|
|
||||||
|
// if there are some comments or empty lines, skip them.
|
||||||
|
using skip_line = ::toml::detail::repeat<toml::detail::sequence<
|
||||||
|
::toml::detail::maybe<::toml::detail::lex_ws>,
|
||||||
|
::toml::detail::maybe<::toml::detail::lex_comment>,
|
||||||
|
::toml::detail::lex_newline
|
||||||
|
>, ::toml::detail::at_least<1>>;
|
||||||
|
skip_line::invoke(loc);
|
||||||
|
|
||||||
|
// if there are some whitespaces before a value, skip them.
|
||||||
|
using skip_ws = ::toml::detail::repeat<
|
||||||
|
::toml::detail::lex_ws, ::toml::detail::at_least<1>>;
|
||||||
|
skip_ws::invoke(loc);
|
||||||
|
|
||||||
|
// to distinguish arrays and tables, first check it is a table or not.
|
||||||
|
//
|
||||||
|
// "[1,2,3]"_toml; // this is an array
|
||||||
|
// "[table]"_toml; // a table that has an empty table named "table" inside.
|
||||||
|
// "[[1,2,3]]"_toml; // this is an array of arrays
|
||||||
|
// "[[table]]"_toml; // this is a table that has an array of tables inside.
|
||||||
|
//
|
||||||
|
// "[[1]]"_toml; // this can be both... (currently it becomes a table)
|
||||||
|
// "1 = [{}]"_toml; // this is a table that has an array of table named 1.
|
||||||
|
// "[[1,]]"_toml; // this is an array of arrays.
|
||||||
|
// "[[1],]"_toml; // this also.
|
||||||
|
|
||||||
|
const auto the_front = loc.iter();
|
||||||
|
|
||||||
|
const bool is_table_key = ::toml::detail::lex_std_table::invoke(loc);
|
||||||
|
loc.reset(the_front);
|
||||||
|
|
||||||
|
const bool is_aots_key = ::toml::detail::lex_array_table::invoke(loc);
|
||||||
|
loc.reset(the_front);
|
||||||
|
|
||||||
|
// If it is neither a table-key or a array-of-table-key, it may be a value.
|
||||||
|
if(!is_table_key && !is_aots_key)
|
||||||
|
{
|
||||||
|
if(auto data = ::toml::detail::parse_value<::toml::value>(loc))
|
||||||
|
{
|
||||||
|
return data.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that still it can be a table, because the literal might be something
|
||||||
|
// like the following.
|
||||||
|
// ```cpp
|
||||||
|
// R"( // c++11 raw string literals
|
||||||
|
// key = "value"
|
||||||
|
// int = 42
|
||||||
|
// )"_toml;
|
||||||
|
// ```
|
||||||
|
// It is a valid toml file.
|
||||||
|
// It should be parsed as if we parse a file with this content.
|
||||||
|
|
||||||
|
if(auto data = ::toml::detail::parse_toml_file<::toml::value>(loc))
|
||||||
|
{
|
||||||
|
return data.unwrap();
|
||||||
|
}
|
||||||
|
else // none of them.
|
||||||
|
{
|
||||||
|
throw ::toml::syntax_error(data.unwrap_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // toml_literals
|
||||||
|
} // literals
|
||||||
|
} // toml
|
||||||
|
#endif//TOML11_LITERAL_HPP
|
||||||
1219
toml/parser.hpp
1219
toml/parser.hpp
File diff suppressed because it is too large
Load Diff
513
toml/region.hpp
513
toml/region.hpp
@@ -1,7 +1,7 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_REGION_H
|
#ifndef TOML11_REGION_HPP
|
||||||
#define TOML11_REGION_H
|
#define TOML11_REGION_HPP
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -9,13 +9,14 @@
|
|||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
// helper function to avoid std::string(0, 'c')
|
// helper function to avoid std::string(0, 'c') or std::string(iter, iter)
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
std::string make_string(Iterator first, Iterator last)
|
std::string make_string(Iterator first, Iterator last)
|
||||||
{
|
{
|
||||||
@@ -28,47 +29,7 @@ inline std::string make_string(std::size_t len, char c)
|
|||||||
return std::string(len, c);
|
return std::string(len, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// location in a container, normally in a file content.
|
// region_base is a base class of location and region that are defined below.
|
||||||
// shared_ptr points the resource that the iter points.
|
|
||||||
// it can be used not only for resource handling, but also error message.
|
|
||||||
template<typename Container>
|
|
||||||
struct location
|
|
||||||
{
|
|
||||||
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
|
||||||
using const_iterator = typename Container::const_iterator;
|
|
||||||
using source_ptr = std::shared_ptr<const Container>;
|
|
||||||
|
|
||||||
location(std::string name, Container cont)
|
|
||||||
: source_(std::make_shared<Container>(std::move(cont))),
|
|
||||||
source_name_(std::move(name)), iter_(source_->cbegin())
|
|
||||||
{}
|
|
||||||
location(const location&) = default;
|
|
||||||
location(location&&) = default;
|
|
||||||
location& operator=(const location&) = default;
|
|
||||||
location& operator=(location&&) = default;
|
|
||||||
~location() = default;
|
|
||||||
|
|
||||||
const_iterator& iter() noexcept {return iter_;}
|
|
||||||
const_iterator iter() const noexcept {return iter_;}
|
|
||||||
|
|
||||||
const_iterator begin() const noexcept {return source_->cbegin();}
|
|
||||||
const_iterator end() const noexcept {return source_->cend();}
|
|
||||||
|
|
||||||
source_ptr const& source() const& noexcept {return source_;}
|
|
||||||
source_ptr&& source() && noexcept {return std::move(source_);}
|
|
||||||
|
|
||||||
std::string const& name() const noexcept {return source_name_;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
source_ptr source_;
|
|
||||||
std::string source_name_;
|
|
||||||
const_iterator iter_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// region in a container, normally in a file content.
|
|
||||||
// shared_ptr points the resource that the iter points.
|
|
||||||
// combinators returns this.
|
|
||||||
// it will be used to generate better error messages.
|
// it will be used to generate better error messages.
|
||||||
struct region_base
|
struct region_base
|
||||||
{
|
{
|
||||||
@@ -86,19 +47,163 @@ struct region_base
|
|||||||
virtual std::string line() const {return std::string("unknown line");}
|
virtual std::string line() const {return std::string("unknown line");}
|
||||||
virtual std::string line_num() const {return std::string("?");}
|
virtual std::string line_num() const {return std::string("?");}
|
||||||
|
|
||||||
|
// length of the region
|
||||||
virtual std::size_t before() const noexcept {return 0;}
|
|
||||||
virtual std::size_t size() const noexcept {return 0;}
|
virtual std::size_t size() const noexcept {return 0;}
|
||||||
|
// number of characters in the line before the region
|
||||||
|
virtual std::size_t before() const noexcept {return 0;}
|
||||||
|
// number of characters in the line after the region
|
||||||
virtual std::size_t after() const noexcept {return 0;}
|
virtual std::size_t after() const noexcept {return 0;}
|
||||||
|
|
||||||
|
virtual std::vector<std::string> comments()const {return {};}
|
||||||
|
// ```toml
|
||||||
|
// # comment_before
|
||||||
|
// key = "value" # comment_inline
|
||||||
|
// ```
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// location represents a position in a container, which contains a file content.
|
||||||
|
// it can be considered as a region that contains only one character.
|
||||||
|
//
|
||||||
|
// it contains pointer to the file content and iterator that points the current
|
||||||
|
// location.
|
||||||
|
template<typename Container>
|
||||||
|
struct location final : public region_base
|
||||||
|
{
|
||||||
|
using const_iterator = typename Container::const_iterator;
|
||||||
|
using difference_type = typename const_iterator::difference_type;
|
||||||
|
using source_ptr = std::shared_ptr<const Container>;
|
||||||
|
|
||||||
|
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
||||||
|
static_assert(std::is_same<std::random_access_iterator_tag,
|
||||||
|
typename std::iterator_traits<const_iterator>::iterator_category>::value,
|
||||||
|
"container should be randomly accessible");
|
||||||
|
|
||||||
|
location(std::string name, Container cont)
|
||||||
|
: source_(std::make_shared<Container>(std::move(cont))), line_number_(1),
|
||||||
|
source_name_(std::move(name)), iter_(source_->cbegin())
|
||||||
|
{}
|
||||||
|
location(const location&) = default;
|
||||||
|
location(location&&) = default;
|
||||||
|
location& operator=(const location&) = default;
|
||||||
|
location& operator=(location&&) = default;
|
||||||
|
~location() = default;
|
||||||
|
|
||||||
|
bool is_ok() const noexcept override {return static_cast<bool>(source_);}
|
||||||
|
|
||||||
|
// this const prohibits codes like `++(loc.iter())`.
|
||||||
|
const const_iterator iter() const noexcept {return iter_;}
|
||||||
|
|
||||||
|
const_iterator begin() const noexcept {return source_->cbegin();}
|
||||||
|
const_iterator end() const noexcept {return source_->cend();}
|
||||||
|
|
||||||
|
// XXX `location::line_num()` used to be implemented using `std::count` to
|
||||||
|
// count a number of '\n'. But with a long toml file (typically, 10k lines),
|
||||||
|
// it becomes intolerably slow because each time it generates error messages,
|
||||||
|
// it counts '\n' from thousands of characters. To workaround it, I decided
|
||||||
|
// to introduce `location::line_number_` member variable and synchronize it
|
||||||
|
// to the location changes the point to look. So an overload of `iter()`
|
||||||
|
// which returns mutable reference is removed and `advance()`, `retrace()`
|
||||||
|
// and `reset()` is added.
|
||||||
|
void advance(difference_type n = 1) noexcept
|
||||||
|
{
|
||||||
|
this->line_number_ += static_cast<std::size_t>(
|
||||||
|
std::count(this->iter_, std::next(this->iter_, n), '\n'));
|
||||||
|
this->iter_ += n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void retrace(difference_type n = 1) noexcept
|
||||||
|
{
|
||||||
|
this->line_number_ -= static_cast<std::size_t>(
|
||||||
|
std::count(std::prev(this->iter_, n), this->iter_, '\n'));
|
||||||
|
this->iter_ -= n;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void reset(const_iterator rollback) noexcept
|
||||||
|
{
|
||||||
|
// since c++11, std::distance works in both ways for random-access
|
||||||
|
// iterators and returns a negative value if `first > last`.
|
||||||
|
if(0 <= std::distance(rollback, this->iter_)) // rollback < iter
|
||||||
|
{
|
||||||
|
this->line_number_ -= static_cast<std::size_t>(
|
||||||
|
std::count(rollback, this->iter_, '\n'));
|
||||||
|
}
|
||||||
|
else // iter < rollback [[unlikely]]
|
||||||
|
{
|
||||||
|
this->line_number_ += static_cast<std::size_t>(
|
||||||
|
std::count(this->iter_, rollback, '\n'));
|
||||||
|
}
|
||||||
|
this->iter_ = rollback;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string str() const override {return make_string(1, *this->iter());}
|
||||||
|
std::string name() const override {return source_name_;}
|
||||||
|
|
||||||
|
std::string line_num() const override
|
||||||
|
{
|
||||||
|
return std::to_string(this->line_number_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line() const override
|
||||||
|
{
|
||||||
|
return make_string(this->line_begin(), this->line_end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator line_begin() const noexcept
|
||||||
|
{
|
||||||
|
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
return std::find(reverse_iterator(this->iter()),
|
||||||
|
reverse_iterator(this->begin()), '\n').base();
|
||||||
|
}
|
||||||
|
const_iterator line_end() const noexcept
|
||||||
|
{
|
||||||
|
return std::find(this->iter(), this->end(), '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// location is always points a character. so the size is 1.
|
||||||
|
std::size_t size() const noexcept override
|
||||||
|
{
|
||||||
|
return 1u;
|
||||||
|
}
|
||||||
|
std::size_t before() const noexcept override
|
||||||
|
{
|
||||||
|
const auto sz = std::distance(this->line_begin(), this->iter());
|
||||||
|
assert(sz >= 0);
|
||||||
|
return static_cast<std::size_t>(sz);
|
||||||
|
}
|
||||||
|
std::size_t after() const noexcept override
|
||||||
|
{
|
||||||
|
const auto sz = std::distance(this->iter(), this->line_end());
|
||||||
|
assert(sz >= 0);
|
||||||
|
return static_cast<std::size_t>(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
source_ptr const& source() const& noexcept {return source_;}
|
||||||
|
source_ptr&& source() && noexcept {return std::move(source_);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
source_ptr source_;
|
||||||
|
std::size_t line_number_;
|
||||||
|
std::string source_name_;
|
||||||
|
const_iterator iter_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// region represents a range in a container, which contains a file content.
|
||||||
|
//
|
||||||
|
// it contains pointer to the file content and iterator that points the first
|
||||||
|
// and last location.
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
struct region final : public region_base
|
struct region final : public region_base
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
|
||||||
using const_iterator = typename Container::const_iterator;
|
using const_iterator = typename Container::const_iterator;
|
||||||
using source_ptr = std::shared_ptr<const Container>;
|
using source_ptr = std::shared_ptr<const Container>;
|
||||||
|
|
||||||
|
static_assert(std::is_same<char, typename Container::value_type>::value,"");
|
||||||
|
static_assert(std::is_same<std::random_access_iterator_tag,
|
||||||
|
typename std::iterator_traits<const_iterator>::iterator_category>::value,
|
||||||
|
"container should be randomly accessible");
|
||||||
|
|
||||||
// delete default constructor. source_ never be null.
|
// delete default constructor. source_ never be null.
|
||||||
region() = delete;
|
region() = delete;
|
||||||
|
|
||||||
@@ -154,15 +259,21 @@ struct region final : public region_base
|
|||||||
|
|
||||||
std::size_t size() const noexcept override
|
std::size_t size() const noexcept override
|
||||||
{
|
{
|
||||||
return std::distance(first_, last_);
|
const auto sz = std::distance(first_, last_);
|
||||||
|
assert(sz >= 0);
|
||||||
|
return static_cast<std::size_t>(sz);
|
||||||
}
|
}
|
||||||
std::size_t before() const noexcept override
|
std::size_t before() const noexcept override
|
||||||
{
|
{
|
||||||
return std::distance(this->line_begin(), this->first());
|
const auto sz = std::distance(this->line_begin(), this->first());
|
||||||
|
assert(sz >= 0);
|
||||||
|
return static_cast<std::size_t>(sz);
|
||||||
}
|
}
|
||||||
std::size_t after() const noexcept override
|
std::size_t after() const noexcept override
|
||||||
{
|
{
|
||||||
return std::distance(this->last(), this->line_end());
|
const auto sz = std::distance(this->last(), this->line_end());
|
||||||
|
assert(sz >= 0);
|
||||||
|
return static_cast<std::size_t>(sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contain_newline() const noexcept
|
bool contain_newline() const noexcept
|
||||||
@@ -191,6 +302,114 @@ struct region final : public region_base
|
|||||||
|
|
||||||
std::string name() const override {return source_name_;}
|
std::string name() const override {return source_name_;}
|
||||||
|
|
||||||
|
std::vector<std::string> comments() const override
|
||||||
|
{
|
||||||
|
// assuming the current region (`*this`) points a value.
|
||||||
|
// ```toml
|
||||||
|
// a = "value"
|
||||||
|
// ^^^^^^^- this region
|
||||||
|
// ```
|
||||||
|
using rev_iter = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
std::vector<std::string> com{};
|
||||||
|
{
|
||||||
|
// find comments just before the current region.
|
||||||
|
// ```toml
|
||||||
|
// # this should be collected.
|
||||||
|
// # this also.
|
||||||
|
// a = value # not this.
|
||||||
|
// ```
|
||||||
|
|
||||||
|
// # this is a comment for `a`, not array elements.
|
||||||
|
// a = [1, 2, 3, 4, 5]
|
||||||
|
if(this->first() == std::find_if(this->line_begin(), this->first(),
|
||||||
|
[](const char c) noexcept -> bool {return c == '[' || c == '{';}))
|
||||||
|
{
|
||||||
|
auto iter = this->line_begin(); // points the first character
|
||||||
|
while(iter != this->begin())
|
||||||
|
{
|
||||||
|
iter = std::prev(iter);
|
||||||
|
|
||||||
|
// range [line_start, iter) represents the previous line
|
||||||
|
const auto line_start = std::find(
|
||||||
|
rev_iter(iter), rev_iter(this->begin()), '\n').base();
|
||||||
|
const auto comment_found = std::find(line_start, iter, '#');
|
||||||
|
if(comment_found == iter)
|
||||||
|
{
|
||||||
|
break; // comment not found.
|
||||||
|
}
|
||||||
|
|
||||||
|
// exclude the following case.
|
||||||
|
// > a = "foo" # comment // <-- this is not a comment for b but a.
|
||||||
|
// > b = "current value"
|
||||||
|
if(std::all_of(line_start, comment_found,
|
||||||
|
[](const char c) noexcept -> bool {
|
||||||
|
return c == ' ' || c == '\t';
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
// unwrap the first '#' by std::next.
|
||||||
|
auto str = make_string(std::next(comment_found), iter);
|
||||||
|
if(str.back() == '\r') {str.pop_back();}
|
||||||
|
com.push_back(std::move(str));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iter = line_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(com.size() > 1)
|
||||||
|
{
|
||||||
|
std::reverse(com.begin(), com.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// find comments just after the current region.
|
||||||
|
// ```toml
|
||||||
|
// # not this.
|
||||||
|
// a = value # this one.
|
||||||
|
// a = [ # not this (technically difficult)
|
||||||
|
//
|
||||||
|
// ] # and this.
|
||||||
|
// ```
|
||||||
|
// The reason why it's difficult is that it requires parsing in the
|
||||||
|
// following case.
|
||||||
|
// ```toml
|
||||||
|
// a = [ 10 # this comment is for `10`. not for `a` but `a[0]`.
|
||||||
|
// # ...
|
||||||
|
// ] # this is apparently a comment for a.
|
||||||
|
//
|
||||||
|
// b = [
|
||||||
|
// 3.14 ] # there is no way to add a comment to `3.14` currently.
|
||||||
|
//
|
||||||
|
// c = [
|
||||||
|
// 3.14 # do this if you need a comment here.
|
||||||
|
// ]
|
||||||
|
// ```
|
||||||
|
const auto comment_found =
|
||||||
|
std::find(this->last(), this->line_end(), '#');
|
||||||
|
if(comment_found != this->line_end()) // '#' found
|
||||||
|
{
|
||||||
|
// table = {key = "value"} # what is this for?
|
||||||
|
// the above comment is not for "value", but {key="value"}.
|
||||||
|
if(comment_found == std::find_if(this->last(), comment_found,
|
||||||
|
[](const char c) noexcept -> bool {
|
||||||
|
return !(c == ' ' || c == '\t' || c == ',');
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
// unwrap the first '#' by std::next.
|
||||||
|
auto str = make_string(std::next(comment_found), this->line_end());
|
||||||
|
if(str.back() == '\r') {str.pop_back();}
|
||||||
|
com.push_back(std::move(str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return com;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
source_ptr source_;
|
source_ptr source_;
|
||||||
@@ -200,162 +419,76 @@ struct region final : public region_base
|
|||||||
|
|
||||||
// to show a better error message.
|
// to show a better error message.
|
||||||
inline std::string format_underline(const std::string& message,
|
inline std::string format_underline(const std::string& message,
|
||||||
const region_base& reg, const std::string& comment_for_underline,
|
const std::vector<std::pair<region_base const*, std::string>>& reg_com,
|
||||||
std::vector<std::string> helps = {})
|
const std::vector<std::string>& helps = {})
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
assert(!reg_com.empty());
|
||||||
const auto newline = "\r\n";
|
|
||||||
#else
|
|
||||||
const char newline = '\n';
|
|
||||||
#endif
|
|
||||||
const auto line = reg.line();
|
|
||||||
const auto line_number = reg.line_num();
|
|
||||||
|
|
||||||
std::string retval;
|
const auto line_num_width = static_cast<int>(std::max_element(
|
||||||
retval += message;
|
reg_com.begin(), reg_com.end(),
|
||||||
retval += newline;
|
[](std::pair<region_base const*, std::string> const& lhs,
|
||||||
retval += " --> ";
|
std::pair<region_base const*, std::string> const& rhs)
|
||||||
retval += reg.name();
|
|
||||||
retval += newline;
|
|
||||||
retval += ' ';
|
|
||||||
retval += line_number;
|
|
||||||
retval += " | ";
|
|
||||||
retval += line;
|
|
||||||
retval += newline;
|
|
||||||
retval += make_string(line_number.size() + 1, ' ');
|
|
||||||
retval += " | ";
|
|
||||||
retval += make_string(reg.before(), ' ');
|
|
||||||
retval += make_string(reg.size(), '~');
|
|
||||||
retval += ' ';
|
|
||||||
retval += comment_for_underline;
|
|
||||||
if(helps.size() != 0)
|
|
||||||
{
|
|
||||||
retval += newline;
|
|
||||||
retval += make_string(line_number.size() + 1, ' ');
|
|
||||||
retval += " | ";
|
|
||||||
for(const auto help : helps)
|
|
||||||
{
|
{
|
||||||
retval += newline;
|
return lhs.first->line_num().size() < rhs.first->line_num().size();
|
||||||
retval += "Hint: ";
|
|
||||||
retval += help;
|
|
||||||
}
|
}
|
||||||
}
|
)->first->line_num().size());
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
// to show a better error message.
|
|
||||||
inline std::string format_underline(const std::string& message,
|
|
||||||
const region_base& reg1, const std::string& comment_for_underline1,
|
|
||||||
const region_base& reg2, const std::string& comment_for_underline2,
|
|
||||||
std::vector<std::string> helps = {})
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
const auto newline = "\r\n";
|
|
||||||
#else
|
|
||||||
const char newline = '\n';
|
|
||||||
#endif
|
|
||||||
const auto line1 = reg1.line();
|
|
||||||
const auto line_number1 = reg1.line_num();
|
|
||||||
const auto line2 = reg2.line();
|
|
||||||
const auto line_number2 = reg2.line_num();
|
|
||||||
const auto line_num_width =
|
|
||||||
std::max(line_number1.size(), line_number2.size());
|
|
||||||
|
|
||||||
std::ostringstream retval;
|
std::ostringstream retval;
|
||||||
retval << message;
|
retval << message << '\n';
|
||||||
retval << newline;
|
|
||||||
retval << " --> ";
|
for(auto iter = reg_com.begin(); iter != reg_com.end(); ++iter)
|
||||||
retval << reg1.name() << newline;;
|
|
||||||
// ---------------------------------------
|
|
||||||
retval << ' ' << std::setw(line_num_width) << line_number1;
|
|
||||||
retval << " | " << line1 << newline;
|
|
||||||
retval << make_string(line_num_width + 1, ' ');
|
|
||||||
retval << " | ";
|
|
||||||
retval << make_string(reg1.before(), ' ');
|
|
||||||
retval << make_string(reg1.size(), '~');
|
|
||||||
retval << ' ';
|
|
||||||
retval << comment_for_underline1 << newline;
|
|
||||||
// ---------------------------------------
|
|
||||||
retval << " ..." << newline;
|
|
||||||
retval << ' ' << std::setw(line_num_width) << line_number2;
|
|
||||||
retval << " | " << line2 << newline;
|
|
||||||
retval << make_string(line_num_width + 1, ' ');
|
|
||||||
retval << " | ";
|
|
||||||
retval << make_string(reg2.before(), ' ');
|
|
||||||
retval << make_string(reg2.size(), '~');
|
|
||||||
retval << ' ';
|
|
||||||
retval << comment_for_underline2;
|
|
||||||
if(helps.size() != 0)
|
|
||||||
{
|
{
|
||||||
retval << newline;
|
// if the filenames are the same, print "..."
|
||||||
retval << make_string(line_num_width + 1, ' ');
|
if(iter != reg_com.begin() &&
|
||||||
|
std::prev(iter)->first->name() == iter->first->name())
|
||||||
|
{
|
||||||
|
retval << "\n ...\n";
|
||||||
|
}
|
||||||
|
else // if filename differs, print " --> filename.toml"
|
||||||
|
{
|
||||||
|
if(iter != reg_com.begin()) {retval << '\n';}
|
||||||
|
retval << " --> " << iter->first->name() << '\n';
|
||||||
|
}
|
||||||
|
const region_base* const reg = iter->first;
|
||||||
|
const std::string& comment = iter->second;
|
||||||
|
|
||||||
|
retval << ' ' << std::setw(line_num_width) << reg->line_num();
|
||||||
|
retval << " | " << reg->line() << '\n';
|
||||||
|
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
|
||||||
|
retval << " | " << make_string(reg->before(), ' ');
|
||||||
|
|
||||||
|
if(reg->size() == 1)
|
||||||
|
{
|
||||||
|
// invalid
|
||||||
|
// ^------
|
||||||
|
retval << '^';
|
||||||
|
retval << make_string(reg->after(), '-');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// invalid
|
||||||
|
// ~~~~~~~
|
||||||
|
const auto underline_len = std::min(reg->size(), reg->line().size());
|
||||||
|
retval << make_string(underline_len, '~');
|
||||||
|
}
|
||||||
|
retval << ' ';
|
||||||
|
retval << comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!helps.empty())
|
||||||
|
{
|
||||||
|
retval << '\n';
|
||||||
|
retval << make_string(static_cast<std::size_t>(line_num_width + 1), ' ');
|
||||||
retval << " | ";
|
retval << " | ";
|
||||||
for(const auto help : helps)
|
for(const auto help : helps)
|
||||||
{
|
{
|
||||||
retval << newline;
|
retval << "\nHint: ";
|
||||||
retval << "Hint: ";
|
|
||||||
retval << help;
|
retval << help;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retval.str();
|
return retval.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// to show a better error message.
|
|
||||||
template<typename Container>
|
|
||||||
std::string
|
|
||||||
format_underline(const std::string& message, const location<Container>& loc,
|
|
||||||
const std::string& comment_for_underline,
|
|
||||||
std::vector<std::string> helps = {})
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
const auto newline = "\r\n";
|
|
||||||
#else
|
|
||||||
const char newline = '\n';
|
|
||||||
#endif
|
|
||||||
using const_iterator = typename location<Container>::const_iterator;
|
|
||||||
using reverse_iterator = std::reverse_iterator<const_iterator>;
|
|
||||||
const auto line_begin = std::find(reverse_iterator(loc.iter()),
|
|
||||||
reverse_iterator(loc.begin()),
|
|
||||||
'\n').base();
|
|
||||||
const auto line_end = std::find(loc.iter(), loc.end(), '\n');
|
|
||||||
|
|
||||||
const auto line_number = std::to_string(
|
|
||||||
1 + std::count(loc.begin(), loc.iter(), '\n'));
|
|
||||||
|
|
||||||
std::string retval;
|
|
||||||
retval += message;
|
|
||||||
retval += newline;
|
|
||||||
retval += " --> ";
|
|
||||||
retval += loc.name();
|
|
||||||
retval += newline;
|
|
||||||
retval += ' ';
|
|
||||||
retval += line_number;
|
|
||||||
retval += " | ";
|
|
||||||
retval += make_string(line_begin, line_end);
|
|
||||||
retval += newline;
|
|
||||||
retval += make_string(line_number.size() + 1, ' ');
|
|
||||||
retval += " | ";
|
|
||||||
retval += make_string(std::distance(line_begin, loc.iter()),' ');
|
|
||||||
retval += '^';
|
|
||||||
retval += make_string(std::distance(loc.iter(), line_end), '-');
|
|
||||||
retval += ' ';
|
|
||||||
retval += comment_for_underline;
|
|
||||||
if(helps.size() != 0)
|
|
||||||
{
|
|
||||||
retval += newline;
|
|
||||||
retval += make_string(line_number.size() + 1, ' ');
|
|
||||||
retval += " | ";
|
|
||||||
for(const auto help : helps)
|
|
||||||
{
|
|
||||||
retval += newline;
|
|
||||||
retval += "Hint: ";
|
|
||||||
retval += help;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // toml
|
} // toml
|
||||||
#endif// TOML11_REGION_H
|
#endif// TOML11_REGION_H
|
||||||
|
|||||||
157
toml/result.hpp
157
toml/result.hpp
@@ -1,7 +1,8 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_RESULT_H
|
#ifndef TOML11_RESULT_HPP
|
||||||
#define TOML11_RESULT_H
|
#define TOML11_RESULT_HPP
|
||||||
|
#include "traits.hpp"
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -13,19 +14,6 @@
|
|||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
#if __cplusplus >= 201703L
|
|
||||||
|
|
||||||
template<typename F, typename ... Args>
|
|
||||||
using return_type_of_t = std::invoke_result_t<F, Args...>;
|
|
||||||
|
|
||||||
#else
|
|
||||||
// result_of is deprecated after C++17
|
|
||||||
template<typename F, typename ... Args>
|
|
||||||
using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct success
|
struct success
|
||||||
{
|
{
|
||||||
@@ -125,21 +113,25 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
result(const failure_type& f): is_ok_(false)
|
result(const failure_type& f): is_ok_(false)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
result(success_type&& s): is_ok_(true)
|
result(success_type&& s): is_ok_(true)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
result(failure_type&& f): is_ok_(false)
|
result(failure_type&& f): is_ok_(false)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
@@ -147,24 +139,28 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
result(const failure<U>& f): is_ok_(false)
|
result(const failure<U>& f): is_ok_(false)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
result(success<U>&& s): is_ok_(true)
|
result(success<U>&& s): is_ok_(true)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
result(failure<U>&& f): is_ok_(false)
|
result(failure<U>&& f): is_ok_(false)
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
result& operator=(const success_type& s)
|
result& operator=(const success_type& s)
|
||||||
@@ -173,6 +169,7 @@ struct result
|
|||||||
this->is_ok_ = true;
|
this->is_ok_ = true;
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
auto tmp = ::new(std::addressof(this->succ)) success_type(s);
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
result& operator=(const failure_type& f)
|
result& operator=(const failure_type& f)
|
||||||
@@ -181,6 +178,7 @@ struct result
|
|||||||
this->is_ok_ = false;
|
this->is_ok_ = false;
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(f);
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
result& operator=(success_type&& s)
|
result& operator=(success_type&& s)
|
||||||
@@ -189,6 +187,7 @@ struct result
|
|||||||
this->is_ok_ = true;
|
this->is_ok_ = true;
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
result& operator=(failure_type&& f)
|
result& operator=(failure_type&& f)
|
||||||
@@ -197,6 +196,7 @@ struct result
|
|||||||
this->is_ok_ = false;
|
this->is_ok_ = false;
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +207,7 @@ struct result
|
|||||||
this->is_ok_ = true;
|
this->is_ok_ = true;
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
auto tmp = ::new(std::addressof(this->succ)) success_type(s.value);
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
@@ -216,6 +217,7 @@ struct result
|
|||||||
this->is_ok_ = false;
|
this->is_ok_ = false;
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(f.value);
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
@@ -225,6 +227,7 @@ struct result
|
|||||||
this->is_ok_ = true;
|
this->is_ok_ = true;
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(s.value));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
@@ -234,6 +237,7 @@ struct result
|
|||||||
this->is_ok_ = false;
|
this->is_ok_ = false;
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(f.value));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,11 +249,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result(result&& other): is_ok_(other.is_ok())
|
result(result&& other): is_ok_(other.is_ok())
|
||||||
@@ -258,11 +264,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,11 +281,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename U, typename F>
|
template<typename U, typename F>
|
||||||
@@ -287,11 +297,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,11 +314,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
is_ok_ = other.is_ok();
|
is_ok_ = other.is_ok();
|
||||||
return *this;
|
return *this;
|
||||||
@@ -318,11 +332,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
is_ok_ = other.is_ok();
|
is_ok_ = other.is_ok();
|
||||||
return *this;
|
return *this;
|
||||||
@@ -336,11 +352,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
auto tmp = ::new(std::addressof(this->succ)) success_type(other.as_ok());
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(other.as_err());
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
is_ok_ = other.is_ok();
|
is_ok_ = other.is_ok();
|
||||||
return *this;
|
return *this;
|
||||||
@@ -353,11 +371,13 @@ struct result
|
|||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
auto tmp = ::new(std::addressof(this->succ)) success_type(std::move(other.as_ok()));
|
||||||
assert(tmp == std::addressof(this->succ));
|
assert(tmp == std::addressof(this->succ));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
auto tmp = ::new(std::addressof(this->fail)) failure_type(std::move(other.as_err()));
|
||||||
assert(tmp == std::addressof(this->fail));
|
assert(tmp == std::addressof(this->fail));
|
||||||
|
(void)tmp;
|
||||||
}
|
}
|
||||||
is_ok_ = other.is_ok();
|
is_ok_ = other.is_ok();
|
||||||
return *this;
|
return *this;
|
||||||
@@ -396,23 +416,20 @@ struct result
|
|||||||
return std::move(this->succ.value);
|
return std::move(this->succ.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
value_type& unwrap_or(value_type& opt) &
|
||||||
value_type& unwrap_or(U& opt) &
|
|
||||||
{
|
{
|
||||||
if(is_err()) {return opt;}
|
if(is_err()) {return opt;}
|
||||||
return this->succ.value;
|
return this->succ.value;
|
||||||
}
|
}
|
||||||
template<typename U>
|
value_type const& unwrap_or(value_type const& opt) const&
|
||||||
value_type const& unwrap_or(U const& opt) const&
|
|
||||||
{
|
{
|
||||||
if(is_err()) {return opt;}
|
if(is_err()) {return opt;}
|
||||||
return this->succ.value;
|
return this->succ.value;
|
||||||
}
|
}
|
||||||
template<typename U>
|
value_type unwrap_or(value_type opt) &&
|
||||||
value_type&& unwrap_or(U&& opt) &&
|
|
||||||
{
|
{
|
||||||
if(is_err()) {return std::move(opt);}
|
if(is_err()) {return opt;}
|
||||||
return std::move(this->succ.value);
|
return this->succ.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_type& unwrap_err() &
|
error_type& unwrap_err() &
|
||||||
@@ -444,21 +461,21 @@ struct result
|
|||||||
// F: T -> U
|
// F: T -> U
|
||||||
// retval: result<U, E>
|
// retval: result<U, E>
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type&>, error_type>
|
result<detail::return_type_of_t<F, value_type&>, error_type>
|
||||||
map(F&& f) &
|
map(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(this->as_ok()));}
|
if(this->is_ok()){return ok(f(this->as_ok()));}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type const&>, error_type>
|
result<detail::return_type_of_t<F, value_type const&>, error_type>
|
||||||
map(F&& f) const&
|
map(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(this->as_ok()));}
|
if(this->is_ok()){return ok(f(this->as_ok()));}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<return_type_of_t<F, value_type &&>, error_type>
|
result<detail::return_type_of_t<F, value_type &&>, error_type>
|
||||||
map(F&& f) &&
|
map(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return ok(f(std::move(this->as_ok())));}
|
if(this->is_ok()){return ok(f(std::move(this->as_ok())));}
|
||||||
@@ -469,21 +486,21 @@ struct result
|
|||||||
// F: E -> F
|
// F: E -> F
|
||||||
// retval: result<T, F>
|
// retval: result<T, F>
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type&>>
|
result<value_type, detail::return_type_of_t<F, error_type&>>
|
||||||
map_err(F&& f) &
|
map_err(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(this->as_err()));}
|
if(this->is_err()){return err(f(this->as_err()));}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type const&>>
|
result<value_type, detail::return_type_of_t<F, error_type const&>>
|
||||||
map_err(F&& f) const&
|
map_err(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(this->as_err()));}
|
if(this->is_err()){return err(f(this->as_err()));}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
result<value_type, return_type_of_t<F, error_type&&>>
|
result<value_type, detail::return_type_of_t<F, error_type&&>>
|
||||||
map_err(F&& f) &&
|
map_err(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return err(f(std::move(this->as_err())));}
|
if(this->is_err()){return err(f(std::move(this->as_err())));}
|
||||||
@@ -494,21 +511,21 @@ struct result
|
|||||||
// F: T -> U
|
// F: T -> U
|
||||||
// retval: U
|
// retval: U
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type&>
|
detail::return_type_of_t<F, value_type&>
|
||||||
map_or_else(F&& f, U&& opt) &
|
map_or_else(F&& f, U&& opt) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
return f(this->as_ok());
|
return f(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type const&>
|
detail::return_type_of_t<F, value_type const&>
|
||||||
map_or_else(F&& f, U&& opt) const&
|
map_or_else(F&& f, U&& opt) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
return f(this->as_ok());
|
return f(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, value_type&&>
|
detail::return_type_of_t<F, value_type&&>
|
||||||
map_or_else(F&& f, U&& opt) &&
|
map_or_else(F&& f, U&& opt) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return std::forward<U>(opt);}
|
if(this->is_err()){return std::forward<U>(opt);}
|
||||||
@@ -519,21 +536,21 @@ struct result
|
|||||||
// F: E -> U
|
// F: E -> U
|
||||||
// retval: U
|
// retval: U
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type&>
|
detail::return_type_of_t<F, error_type&>
|
||||||
map_err_or_else(F&& f, U&& opt) &
|
map_err_or_else(F&& f, U&& opt) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
return f(this->as_err());
|
return f(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type const&>
|
detail::return_type_of_t<F, error_type const&>
|
||||||
map_err_or_else(F&& f, U&& opt) const&
|
map_err_or_else(F&& f, U&& opt) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
return f(this->as_err());
|
return f(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F, typename U>
|
template<typename F, typename U>
|
||||||
return_type_of_t<F, error_type&&>
|
detail::return_type_of_t<F, error_type&&>
|
||||||
map_err_or_else(F&& f, U&& opt) &&
|
map_err_or_else(F&& f, U&& opt) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return std::forward<U>(opt);}
|
if(this->is_ok()){return std::forward<U>(opt);}
|
||||||
@@ -545,21 +562,21 @@ struct result
|
|||||||
// toml::err(error_type) should be convertible to U.
|
// toml::err(error_type) should be convertible to U.
|
||||||
// normally, type U is another result<S, F> and E is convertible to F
|
// normally, type U is another result<S, F> and E is convertible to F
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type&>
|
detail::return_type_of_t<F, value_type&>
|
||||||
and_then(F&& f) &
|
and_then(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(this->as_ok());}
|
if(this->is_ok()){return f(this->as_ok());}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type const&>
|
detail::return_type_of_t<F, value_type const&>
|
||||||
and_then(F&& f) const&
|
and_then(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(this->as_ok());}
|
if(this->is_ok()){return f(this->as_ok());}
|
||||||
return err(this->as_err());
|
return err(this->as_err());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, value_type&&>
|
detail::return_type_of_t<F, value_type&&>
|
||||||
and_then(F&& f) &&
|
and_then(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_ok()){return f(std::move(this->as_ok()));}
|
if(this->is_ok()){return f(std::move(this->as_ok()));}
|
||||||
@@ -571,27 +588,47 @@ struct result
|
|||||||
// toml::ok(value_type) should be convertible to U.
|
// toml::ok(value_type) should be convertible to U.
|
||||||
// normally, type U is another result<S, F> and T is convertible to S
|
// normally, type U is another result<S, F> and T is convertible to S
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type&>
|
detail::return_type_of_t<F, error_type&>
|
||||||
or_else(F&& f) &
|
or_else(F&& f) &
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(this->as_err());}
|
if(this->is_err()){return f(this->as_err());}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type const&>
|
detail::return_type_of_t<F, error_type const&>
|
||||||
or_else(F&& f) const&
|
or_else(F&& f) const&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(this->as_err());}
|
if(this->is_err()){return f(this->as_err());}
|
||||||
return ok(this->as_ok());
|
return ok(this->as_ok());
|
||||||
}
|
}
|
||||||
template<typename F>
|
template<typename F>
|
||||||
return_type_of_t<F, error_type&&>
|
detail::return_type_of_t<F, error_type&&>
|
||||||
or_else(F&& f) &&
|
or_else(F&& f) &&
|
||||||
{
|
{
|
||||||
if(this->is_err()){return f(std::move(this->as_err()));}
|
if(this->is_err()){return f(std::move(this->as_err()));}
|
||||||
return ok(std::move(this->as_ok()));
|
return ok(std::move(this->as_ok()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if *this is error, returns *this. otherwise, returns other.
|
||||||
|
result and_other(const result& other) const&
|
||||||
|
{
|
||||||
|
return this->is_err() ? *this : other;
|
||||||
|
}
|
||||||
|
result and_other(result&& other) &&
|
||||||
|
{
|
||||||
|
return this->is_err() ? std::move(*this) : std::move(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if *this is okay, returns *this. otherwise, returns other.
|
||||||
|
result or_other(const result& other) const&
|
||||||
|
{
|
||||||
|
return this->is_ok() ? *this : other;
|
||||||
|
}
|
||||||
|
result or_other(result&& other) &&
|
||||||
|
{
|
||||||
|
return this->is_ok() ? std::move(*this) : std::move(other);
|
||||||
|
}
|
||||||
|
|
||||||
void swap(result<T, E>& other)
|
void swap(result<T, E>& other)
|
||||||
{
|
{
|
||||||
result<T, E> tmp(std::move(*this));
|
result<T, E> tmp(std::move(*this));
|
||||||
@@ -638,5 +675,43 @@ void swap(result<T, E>& lhs, result<T, E>& rhs)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this might be confusing because it eagerly evaluated, while in the other
|
||||||
|
// cases operator && and || are short-circuited.
|
||||||
|
//
|
||||||
|
// template<typename T, typename E>
|
||||||
|
// inline result<T, E>
|
||||||
|
// operator&&(const result<T, E>& lhs, const result<T, E>& rhs) noexcept
|
||||||
|
// {
|
||||||
|
// return lhs.is_ok() ? rhs : lhs;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// template<typename T, typename E>
|
||||||
|
// inline result<T, E>
|
||||||
|
// operator||(const result<T, E>& lhs, const result<T, E>& rhs) noexcept
|
||||||
|
// {
|
||||||
|
// return lhs.is_ok() ? lhs : rhs;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// re-use result<T, E> as a optional<T> with none_t
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct none_t {};
|
||||||
|
inline bool operator==(const none_t&, const none_t&) noexcept {return true;}
|
||||||
|
inline bool operator!=(const none_t&, const none_t&) noexcept {return false;}
|
||||||
|
inline bool operator< (const none_t&, const none_t&) noexcept {return false;}
|
||||||
|
inline bool operator<=(const none_t&, const none_t&) noexcept {return true;}
|
||||||
|
inline bool operator> (const none_t&, const none_t&) noexcept {return false;}
|
||||||
|
inline bool operator>=(const none_t&, const none_t&) noexcept {return true;}
|
||||||
|
template<typename charT, typename traitsT>
|
||||||
|
std::basic_ostream<charT, traitsT>&
|
||||||
|
operator<<(std::basic_ostream<charT, traitsT>& os, const none_t&)
|
||||||
|
{
|
||||||
|
os << "none";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
inline failure<none_t> none() noexcept {return failure<none_t>{none_t{}};}
|
||||||
|
} // detail
|
||||||
} // toml11
|
} // toml11
|
||||||
#endif// TOML11_RESULT_H
|
#endif// TOML11_RESULT_H
|
||||||
|
|||||||
672
toml/serializer.hpp
Normal file
672
toml/serializer.hpp
Normal file
@@ -0,0 +1,672 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_SERIALIZER_HPP
|
||||||
|
#define TOML11_SERIALIZER_HPP
|
||||||
|
#include "value.hpp"
|
||||||
|
#include "lexer.hpp"
|
||||||
|
#include <limits>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename Comment,
|
||||||
|
template<typename ...> class Table,
|
||||||
|
template<typename ...> class Array>
|
||||||
|
struct serializer
|
||||||
|
{
|
||||||
|
using value_type = basic_value<Comment, Table, Array>;
|
||||||
|
using key_type = typename value_type::key_type ;
|
||||||
|
using comment_type = typename value_type::comment_type ;
|
||||||
|
using boolean_type = typename value_type::boolean_type ;
|
||||||
|
using integer_type = typename value_type::integer_type ;
|
||||||
|
using floating_type = typename value_type::floating_type ;
|
||||||
|
using string_type = typename value_type::string_type ;
|
||||||
|
using local_time_type = typename value_type::local_time_type ;
|
||||||
|
using local_date_type = typename value_type::local_date_type ;
|
||||||
|
using local_datetime_type = typename value_type::local_datetime_type ;
|
||||||
|
using offset_datetime_type = typename value_type::offset_datetime_type;
|
||||||
|
using array_type = typename value_type::array_type ;
|
||||||
|
using table_type = typename value_type::table_type ;
|
||||||
|
|
||||||
|
serializer(const std::size_t w = 80u,
|
||||||
|
const int float_prec = std::numeric_limits<toml::floating>::max_digits10,
|
||||||
|
const bool can_be_inlined = false,
|
||||||
|
std::vector<toml::key> ks = {})
|
||||||
|
: can_be_inlined_(can_be_inlined), float_prec_(float_prec), width_(w),
|
||||||
|
keys_(std::move(ks))
|
||||||
|
{}
|
||||||
|
~serializer() = default;
|
||||||
|
|
||||||
|
std::string operator()(const boolean_type& b) const
|
||||||
|
{
|
||||||
|
return b ? "true" : "false";
|
||||||
|
}
|
||||||
|
std::string operator()(const integer_type i) const
|
||||||
|
{
|
||||||
|
return std::to_string(i);
|
||||||
|
}
|
||||||
|
std::string operator()(const floating_type f) const
|
||||||
|
{
|
||||||
|
const auto fmt = "%.*g";
|
||||||
|
const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f);
|
||||||
|
// +1 for null character(\0)
|
||||||
|
std::vector<char> buf(static_cast<std::size_t>(bsz + 1), '\0');
|
||||||
|
std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f);
|
||||||
|
|
||||||
|
std::string token(buf.begin(), std::prev(buf.end()));
|
||||||
|
if(token.back() == '.') // 1. => 1.0
|
||||||
|
{
|
||||||
|
token += '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto e = std::find_if(
|
||||||
|
token.cbegin(), token.cend(), [](const char c) noexcept -> bool {
|
||||||
|
return c == 'e' || c == 'E';
|
||||||
|
});
|
||||||
|
const auto has_exponent = (token.cend() != e);
|
||||||
|
const auto has_fraction = (token.cend() != std::find(
|
||||||
|
token.cbegin(), token.cend(), '.'));
|
||||||
|
|
||||||
|
if(!has_exponent && !has_fraction)
|
||||||
|
{
|
||||||
|
// the resulting value does not have any float specific part!
|
||||||
|
token += ".0";
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
if(!has_exponent)
|
||||||
|
{
|
||||||
|
return token; // there is no exponent part. just return it.
|
||||||
|
}
|
||||||
|
|
||||||
|
// zero-prefix in an exponent is NOT allowed in TOML.
|
||||||
|
// remove it if it exists.
|
||||||
|
bool sign_exists = false;
|
||||||
|
std::size_t zero_prefix = 0;
|
||||||
|
for(auto iter = std::next(e), iend = token.cend(); iter != iend; ++iter)
|
||||||
|
{
|
||||||
|
if(*iter == '+' || *iter == '-'){sign_exists = true; continue;}
|
||||||
|
if(*iter == '0'){zero_prefix += 1;}
|
||||||
|
else {break;}
|
||||||
|
}
|
||||||
|
if(zero_prefix != 0)
|
||||||
|
{
|
||||||
|
const auto offset = std::distance(token.cbegin(), e) +
|
||||||
|
(sign_exists ? 2 : 1);
|
||||||
|
token.erase(static_cast<typename std::string::size_type>(offset),
|
||||||
|
zero_prefix);
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
std::string operator()(const string_type& s) const
|
||||||
|
{
|
||||||
|
if(s.kind == string_t::basic)
|
||||||
|
{
|
||||||
|
if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend())
|
||||||
|
{
|
||||||
|
// if linefeed is contained, make it multiline-string.
|
||||||
|
const std::string open("\"\"\"\n");
|
||||||
|
const std::string close("\\\n\"\"\"");
|
||||||
|
return open + this->escape_ml_basic_string(s.str) + close;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no linefeed. try to make it oneline-string.
|
||||||
|
std::string oneline = this->escape_basic_string(s.str);
|
||||||
|
if(oneline.size() + 2 < width_ || width_ < 2)
|
||||||
|
{
|
||||||
|
const std::string quote("\"");
|
||||||
|
return quote + oneline + quote;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the line is too long compared to the specified width.
|
||||||
|
// split it into multiple lines.
|
||||||
|
std::string token("\"\"\"\n");
|
||||||
|
while(!oneline.empty())
|
||||||
|
{
|
||||||
|
if(oneline.size() < width_)
|
||||||
|
{
|
||||||
|
token += oneline;
|
||||||
|
oneline.clear();
|
||||||
|
}
|
||||||
|
else if(oneline.at(width_-2) == '\\')
|
||||||
|
{
|
||||||
|
token += oneline.substr(0, width_-2);
|
||||||
|
token += "\\\n";
|
||||||
|
oneline.erase(0, width_-2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token += oneline.substr(0, width_-1);
|
||||||
|
token += "\\\n";
|
||||||
|
oneline.erase(0, width_-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return token + std::string("\\\n\"\"\"");
|
||||||
|
}
|
||||||
|
else // the string `s` is literal-string.
|
||||||
|
{
|
||||||
|
if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() ||
|
||||||
|
std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() )
|
||||||
|
{
|
||||||
|
const std::string open("'''\n");
|
||||||
|
const std::string close("'''");
|
||||||
|
return open + s.str + close;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const std::string quote("'");
|
||||||
|
return quote + s.str + quote;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const local_date_type& d) const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << d;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
std::string operator()(const local_time_type& t) const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << t;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
std::string operator()(const local_datetime_type& dt) const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << dt;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
std::string operator()(const offset_datetime_type& odt) const
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << odt;
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const array_type& v) const
|
||||||
|
{
|
||||||
|
if(!v.empty() && v.front().is_table())// v is an array of tables
|
||||||
|
{
|
||||||
|
// if it's not inlined, we need to add `[[table.key]]`.
|
||||||
|
// but if it can be inlined,
|
||||||
|
// ```
|
||||||
|
// table.key = [
|
||||||
|
// {...},
|
||||||
|
// # comment
|
||||||
|
// {...},
|
||||||
|
// ]
|
||||||
|
// ```
|
||||||
|
if(this->can_be_inlined_)
|
||||||
|
{
|
||||||
|
std::string token;
|
||||||
|
if(!keys_.empty())
|
||||||
|
{
|
||||||
|
token += this->serialize_key(keys_.back());
|
||||||
|
token += " = ";
|
||||||
|
}
|
||||||
|
bool failed = false;
|
||||||
|
token += "[\n";
|
||||||
|
for(const auto& item : v)
|
||||||
|
{
|
||||||
|
// if an element of the table has a comment, the table
|
||||||
|
// cannot be inlined.
|
||||||
|
if(this->has_comment_inside(item.as_table()))
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(const auto& c : item.comments())
|
||||||
|
{
|
||||||
|
token += '#';
|
||||||
|
token += c;
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto t = this->make_inline_table(item.as_table());
|
||||||
|
|
||||||
|
if(t.size() + 1 > width_ || // +1 for the last comma {...},
|
||||||
|
std::find(t.cbegin(), t.cend(), '\n') != t.cend())
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token += t;
|
||||||
|
token += ",\n";
|
||||||
|
}
|
||||||
|
if(!failed)
|
||||||
|
{
|
||||||
|
token += "]\n";
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
// if failed, serialize them as [[array.of.tables]].
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string token;
|
||||||
|
for(const auto& item : v)
|
||||||
|
{
|
||||||
|
for(const auto& c : item.comments())
|
||||||
|
{
|
||||||
|
token += '#';
|
||||||
|
token += c;
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
token += "[[";
|
||||||
|
token += this->serialize_dotted_key(keys_);
|
||||||
|
token += "]]\n";
|
||||||
|
token += this->make_multiline_table(item.as_table());
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
if(v.empty())
|
||||||
|
{
|
||||||
|
return std::string("[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// not an array of tables. normal array.
|
||||||
|
// first, try to make it inline if none of the elements have a comment.
|
||||||
|
if(!this->has_comment_inside(v))
|
||||||
|
{
|
||||||
|
const auto inl = this->make_inline_array(v);
|
||||||
|
if(inl.size() < this->width_ &&
|
||||||
|
std::find(inl.cbegin(), inl.cend(), '\n') == inl.cend())
|
||||||
|
{
|
||||||
|
return inl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the length exceeds this->width_, print multiline array.
|
||||||
|
// key = [
|
||||||
|
// # ...
|
||||||
|
// 42,
|
||||||
|
// ...
|
||||||
|
// ]
|
||||||
|
std::string token;
|
||||||
|
std::string current_line;
|
||||||
|
token += "[\n";
|
||||||
|
for(const auto& item : v)
|
||||||
|
{
|
||||||
|
if(!item.comments().empty())
|
||||||
|
{
|
||||||
|
// if comment exists, the element must be the only element in the line.
|
||||||
|
// e.g. the following is not allowed.
|
||||||
|
// ```toml
|
||||||
|
// array = [
|
||||||
|
// # comment for what?
|
||||||
|
// 1, 2, 3, 4, 5
|
||||||
|
// ]
|
||||||
|
// ```
|
||||||
|
if(!current_line.empty())
|
||||||
|
{
|
||||||
|
if(current_line.back() != '\n')
|
||||||
|
{
|
||||||
|
current_line += '\n';
|
||||||
|
}
|
||||||
|
token += current_line;
|
||||||
|
current_line.clear();
|
||||||
|
}
|
||||||
|
for(const auto& c : item.comments())
|
||||||
|
{
|
||||||
|
token += '#';
|
||||||
|
token += c;
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
token += toml::visit(*this, item);
|
||||||
|
if(token.back() == '\n') {token.pop_back();}
|
||||||
|
token += ",\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string next_elem;
|
||||||
|
next_elem += toml::visit(*this, item);
|
||||||
|
|
||||||
|
// comma before newline.
|
||||||
|
if(next_elem.back() == '\n') {next_elem.pop_back();}
|
||||||
|
|
||||||
|
// if current line does not exceeds the width limit, continue.
|
||||||
|
if(current_line.size() + next_elem.size() + 1 < this->width_)
|
||||||
|
{
|
||||||
|
current_line += next_elem;
|
||||||
|
current_line += ',';
|
||||||
|
}
|
||||||
|
else if(current_line.empty())
|
||||||
|
{
|
||||||
|
// if current line was empty, force put the next_elem because
|
||||||
|
// next_elem is not splittable
|
||||||
|
token += next_elem;
|
||||||
|
token += ",\n";
|
||||||
|
// current_line is kept empty
|
||||||
|
}
|
||||||
|
else // reset current_line
|
||||||
|
{
|
||||||
|
assert(current_line.back() == ',');
|
||||||
|
token += current_line;
|
||||||
|
token += '\n';
|
||||||
|
current_line = next_elem;
|
||||||
|
current_line += ',';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!current_line.empty())
|
||||||
|
{
|
||||||
|
if(current_line.back() != '\n') {current_line += '\n';}
|
||||||
|
token += current_line;
|
||||||
|
}
|
||||||
|
token += "]\n";
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// templatize for any table-like container
|
||||||
|
std::string operator()(const table_type& v) const
|
||||||
|
{
|
||||||
|
// if an element has a comment, then it can't be inlined.
|
||||||
|
// table = {# how can we write a comment for this? key = "value"}
|
||||||
|
if(this->can_be_inlined_ && !(this->has_comment_inside(v)))
|
||||||
|
{
|
||||||
|
std::string token;
|
||||||
|
if(!this->keys_.empty())
|
||||||
|
{
|
||||||
|
token += this->serialize_key(this->keys_.back());
|
||||||
|
token += " = ";
|
||||||
|
}
|
||||||
|
token += this->make_inline_table(v);
|
||||||
|
if(token.size() < this->width_)
|
||||||
|
{
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string token;
|
||||||
|
if(!keys_.empty())
|
||||||
|
{
|
||||||
|
token += '[';
|
||||||
|
token += this->serialize_dotted_key(keys_);
|
||||||
|
token += "]\n";
|
||||||
|
}
|
||||||
|
token += this->make_multiline_table(v);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string serialize_key(const toml::key& key) const
|
||||||
|
{
|
||||||
|
detail::location<toml::key> loc(key, key);
|
||||||
|
detail::lex_unquoted_key::invoke(loc);
|
||||||
|
if(loc.iter() == loc.end())
|
||||||
|
{
|
||||||
|
return key; // all the tokens are consumed. the key is unquoted-key.
|
||||||
|
}
|
||||||
|
std::string token("\"");
|
||||||
|
token += this->escape_basic_string(key);
|
||||||
|
token += "\"";
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string serialize_dotted_key(const std::vector<toml::key>& keys) const
|
||||||
|
{
|
||||||
|
std::string token;
|
||||||
|
if(keys.empty()){return token;}
|
||||||
|
|
||||||
|
for(const auto& k : keys)
|
||||||
|
{
|
||||||
|
token += this->serialize_key(k);
|
||||||
|
token += '.';
|
||||||
|
}
|
||||||
|
token.erase(token.size() - 1, 1); // remove trailing `.`
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string escape_basic_string(const std::string& s) const
|
||||||
|
{
|
||||||
|
//XXX assuming `s` is a valid utf-8 sequence.
|
||||||
|
std::string retval;
|
||||||
|
for(const char c : s)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case '\\': {retval += "\\\\"; break;}
|
||||||
|
case '\"': {retval += "\\\""; break;}
|
||||||
|
case '\b': {retval += "\\b"; break;}
|
||||||
|
case '\t': {retval += "\\t"; break;}
|
||||||
|
case '\f': {retval += "\\f"; break;}
|
||||||
|
case '\n': {retval += "\\n"; break;}
|
||||||
|
case '\r': {retval += "\\r"; break;}
|
||||||
|
default : {retval += c; break;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string escape_ml_basic_string(const std::string& s) const
|
||||||
|
{
|
||||||
|
std::string retval;
|
||||||
|
for(auto i=s.cbegin(), e=s.cend(); i!=e; ++i)
|
||||||
|
{
|
||||||
|
switch(*i)
|
||||||
|
{
|
||||||
|
case '\\': {retval += "\\\\"; break;}
|
||||||
|
case '\"': {retval += "\\\""; break;}
|
||||||
|
case '\b': {retval += "\\b"; break;}
|
||||||
|
case '\t': {retval += "\\t"; break;}
|
||||||
|
case '\f': {retval += "\\f"; break;}
|
||||||
|
case '\n': {retval += "\n"; break;}
|
||||||
|
case '\r':
|
||||||
|
{
|
||||||
|
if(std::next(i) != e && *std::next(i) == '\n')
|
||||||
|
{
|
||||||
|
retval += "\r\n";
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retval += "\\r";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {retval += *i; break;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if an element of a table or an array has a comment, it cannot be inlined.
|
||||||
|
bool has_comment_inside(const array_type& a) const noexcept
|
||||||
|
{
|
||||||
|
for(const auto& v : a)
|
||||||
|
{
|
||||||
|
if(!v.comments().empty()) {return true;}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool has_comment_inside(const table_type& t) const noexcept
|
||||||
|
{
|
||||||
|
for(const auto& kv : t)
|
||||||
|
{
|
||||||
|
if(!kv.second.comments().empty()) {return true;}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string make_inline_array(const array_type& v) const
|
||||||
|
{
|
||||||
|
assert(!has_comment_inside(v));
|
||||||
|
std::string token;
|
||||||
|
token += '[';
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto& item : v)
|
||||||
|
{
|
||||||
|
if(is_first) {is_first = false;} else {token += ',';}
|
||||||
|
token += visit(serializer(std::numeric_limits<std::size_t>::max(),
|
||||||
|
this->float_prec_, true), item);
|
||||||
|
}
|
||||||
|
token += ']';
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string make_inline_table(const table_type& v) const
|
||||||
|
{
|
||||||
|
assert(!has_comment_inside(v));
|
||||||
|
assert(this->can_be_inlined_);
|
||||||
|
std::string token;
|
||||||
|
token += '{';
|
||||||
|
bool is_first = true;
|
||||||
|
for(const auto& kv : v)
|
||||||
|
{
|
||||||
|
// in inline tables, trailing comma is not allowed (toml-lang #569).
|
||||||
|
if(is_first) {is_first = false;} else {token += ',';}
|
||||||
|
token += this->serialize_key(kv.first);
|
||||||
|
token += '=';
|
||||||
|
token += visit(serializer(std::numeric_limits<std::size_t>::max(),
|
||||||
|
this->float_prec_, true), kv.second);
|
||||||
|
}
|
||||||
|
token += '}';
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string make_multiline_table(const table_type& v) const
|
||||||
|
{
|
||||||
|
std::string token;
|
||||||
|
|
||||||
|
// print non-table stuff first. because after printing [foo.bar], the
|
||||||
|
// remaining non-table values will be assigned into [foo.bar], not [foo]
|
||||||
|
for(const auto kv : v)
|
||||||
|
{
|
||||||
|
if(kv.second.is_table() || is_array_of_tables(kv.second))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!kv.second.comments().empty())
|
||||||
|
{
|
||||||
|
for(const auto& c : kv.second.comments())
|
||||||
|
{
|
||||||
|
token += '#';
|
||||||
|
token += c;
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto key_and_sep = this->serialize_key(kv.first) + " = ";
|
||||||
|
const auto residual_width = (this->width_ > key_and_sep.size()) ?
|
||||||
|
this->width_ - key_and_sep.size() : 0;
|
||||||
|
token += key_and_sep;
|
||||||
|
token += visit(serializer(residual_width, this->float_prec_, true),
|
||||||
|
kv.second);
|
||||||
|
if(token.back() != '\n')
|
||||||
|
{
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal tables / array of tables
|
||||||
|
|
||||||
|
// after multiline table appeared, the other tables cannot be inline
|
||||||
|
// because the table would be assigned into the table.
|
||||||
|
// [foo]
|
||||||
|
// ...
|
||||||
|
// bar = {...} # <- bar will be a member of [foo].
|
||||||
|
bool multiline_table_printed = false;
|
||||||
|
for(const auto& kv : v)
|
||||||
|
{
|
||||||
|
if(!kv.second.is_table() && !is_array_of_tables(kv.second))
|
||||||
|
{
|
||||||
|
continue; // other stuff are already serialized. skip them.
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<toml::key> ks(this->keys_);
|
||||||
|
ks.push_back(kv.first);
|
||||||
|
|
||||||
|
auto tmp = visit(serializer(
|
||||||
|
this->width_, this->float_prec_, !multiline_table_printed, ks),
|
||||||
|
kv.second);
|
||||||
|
|
||||||
|
if((!multiline_table_printed) &&
|
||||||
|
std::find(tmp.cbegin(), tmp.cend(), '\n') != tmp.cend())
|
||||||
|
{
|
||||||
|
multiline_table_printed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// still inline tables only.
|
||||||
|
tmp += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!kv.second.comments().empty())
|
||||||
|
{
|
||||||
|
for(const auto& c : kv.second.comments())
|
||||||
|
{
|
||||||
|
token += '#';
|
||||||
|
token += c;
|
||||||
|
token += '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token += tmp;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_array_of_tables(const value_type& v) const
|
||||||
|
{
|
||||||
|
if(!v.is_array()) {return false;}
|
||||||
|
const auto& a = v.as_array();
|
||||||
|
return !a.empty() && a.front().is_table();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool can_be_inlined_;
|
||||||
|
int float_prec_;
|
||||||
|
std::size_t width_;
|
||||||
|
std::vector<toml::key> keys_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
std::string
|
||||||
|
format(const basic_value<C, M, V>& v, std::size_t w = 80u,
|
||||||
|
int fprec = std::numeric_limits<toml::floating>::max_digits10,
|
||||||
|
bool force_inline = false)
|
||||||
|
{
|
||||||
|
// if value is a table, it is considered to be a root object.
|
||||||
|
// the root object can't be an inline table.
|
||||||
|
if(v.is_table())
|
||||||
|
{
|
||||||
|
std::ostringstream oss;
|
||||||
|
if(!v.comments().empty())
|
||||||
|
{
|
||||||
|
for(const auto& c : v.comments())
|
||||||
|
{
|
||||||
|
oss << '#' << c << '\n';
|
||||||
|
}
|
||||||
|
oss << '\n';
|
||||||
|
}
|
||||||
|
oss << visit(serializer<C, M, V>(w, fprec, false), v);
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
return visit(serializer<C, M, V>(w, fprec, force_inline), v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename charT, typename traits, typename C,
|
||||||
|
template<typename ...> class M, template<typename ...> class V>
|
||||||
|
std::basic_ostream<charT, traits>&
|
||||||
|
operator<<(std::basic_ostream<charT, traits>& os, const basic_value<C, M, V>& v)
|
||||||
|
{
|
||||||
|
// get status of std::setw().
|
||||||
|
const auto w = static_cast<std::size_t>(os.width());
|
||||||
|
const int fprec = static_cast<int>(os.precision());
|
||||||
|
os.width(0);
|
||||||
|
|
||||||
|
if(!v.comments().empty())
|
||||||
|
{
|
||||||
|
for(const auto& c : v.comments())
|
||||||
|
{
|
||||||
|
os << '#' << c << '\n';
|
||||||
|
}
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
// the root object can't be an inline table. so pass `false`.
|
||||||
|
os << visit(serializer<C, M, V>(w, fprec, false), v);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // toml
|
||||||
|
#endif// TOML11_SERIALIZER_HPP
|
||||||
82
toml/source_location.hpp
Normal file
82
toml/source_location.hpp
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright Toru Niina 2019.
|
||||||
|
// Distributed under the MIT License.
|
||||||
|
#ifndef TOML11_SOURCE_LOCATION_HPP
|
||||||
|
#define TOML11_SOURCE_LOCATION_HPP
|
||||||
|
#include "region.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace toml
|
||||||
|
{
|
||||||
|
|
||||||
|
// A struct to contain location in a toml file.
|
||||||
|
// The interface imitates std::experimental::source_location,
|
||||||
|
// but not completely the same.
|
||||||
|
//
|
||||||
|
// It would be constructed by toml::value. It can be used to generate
|
||||||
|
// user-defined error messages.
|
||||||
|
//
|
||||||
|
// - std::uint_least32_t line() const noexcept
|
||||||
|
// - returns the line number where the region is on.
|
||||||
|
// - std::uint_least32_t column() const noexcept
|
||||||
|
// - returns the column number where the region starts.
|
||||||
|
// - std::uint_least32_t region() const noexcept
|
||||||
|
// - returns the size of the region.
|
||||||
|
//
|
||||||
|
// +-- line() +-- region of interest (region() == 9)
|
||||||
|
// v .---+---.
|
||||||
|
// 12 | value = "foo bar"
|
||||||
|
// ^
|
||||||
|
// +-- column()
|
||||||
|
//
|
||||||
|
// - std::string const& file_name() const noexcept;
|
||||||
|
// - name of the file.
|
||||||
|
// - std::string const& line_str() const noexcept;
|
||||||
|
// - the whole line that contains the region of interest.
|
||||||
|
//
|
||||||
|
struct source_location
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
source_location()
|
||||||
|
: line_num_(0), column_num_(0), region_size_(0),
|
||||||
|
file_name_("unknown file"), line_str_("")
|
||||||
|
{}
|
||||||
|
|
||||||
|
explicit source_location(const detail::region_base* reg)
|
||||||
|
: line_num_(0), column_num_(0), region_size_(0),
|
||||||
|
file_name_("unknown file"), line_str_("")
|
||||||
|
{
|
||||||
|
if(reg)
|
||||||
|
{
|
||||||
|
line_num_ = static_cast<std::uint_least32_t>(std::stoul(reg->line_num()));
|
||||||
|
column_num_ = static_cast<std::uint_least32_t>(reg->before() + 1);
|
||||||
|
region_size_ = static_cast<std::uint_least32_t>(reg->size());
|
||||||
|
file_name_ = reg->name();
|
||||||
|
line_str_ = reg->line();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~source_location() = default;
|
||||||
|
source_location(source_location const&) = default;
|
||||||
|
source_location(source_location &&) = default;
|
||||||
|
source_location& operator=(source_location const&) = default;
|
||||||
|
source_location& operator=(source_location &&) = default;
|
||||||
|
|
||||||
|
std::uint_least32_t line() const noexcept {return line_num_;}
|
||||||
|
std::uint_least32_t column() const noexcept {return column_num_;}
|
||||||
|
std::uint_least32_t region() const noexcept {return region_size_;}
|
||||||
|
|
||||||
|
std::string const& file_name() const noexcept {return file_name_;}
|
||||||
|
std::string const& line_str() const noexcept {return line_str_;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::uint_least32_t line_num_;
|
||||||
|
std::uint_least32_t column_num_;
|
||||||
|
std::uint_least32_t region_size_;
|
||||||
|
std::string file_name_;
|
||||||
|
std::string line_str_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // toml
|
||||||
|
#endif// TOML11_SOURCE_LOCATION_HPP
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_STRING_H
|
#ifndef TOML11_STRING_HPP
|
||||||
#define TOML11_STRING_H
|
#define TOML11_STRING_HPP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#if __has_include(<string_view>)
|
||||||
|
#include <string_view>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
@@ -40,6 +45,17 @@ struct string
|
|||||||
operator std::string const& () const& noexcept {return str;}
|
operator std::string const& () const& noexcept {return str;}
|
||||||
operator std::string&& () && noexcept {return std::move(str);}
|
operator std::string&& () && noexcept {return std::move(str);}
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
explicit string(std::string_view s): kind(string_t::basic), str(s){}
|
||||||
|
string(std::string_view s, string_t k): kind(k), str(s){}
|
||||||
|
|
||||||
|
string& operator=(std::string_view s)
|
||||||
|
{kind = string_t::basic; str = s; return *this;}
|
||||||
|
|
||||||
|
explicit operator std::string_view() const noexcept
|
||||||
|
{return std::string_view(str);}
|
||||||
|
#endif
|
||||||
|
|
||||||
string_t kind;
|
string_t kind;
|
||||||
std::string str;
|
std::string str;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
// Copyright Toru Niina 2017.
|
|
||||||
// Distributed under the MIT License.
|
|
||||||
#ifndef TOML11_TO_TOML
|
|
||||||
#define TOML11_TO_TOML
|
|
||||||
#include "value.hpp"
|
|
||||||
|
|
||||||
namespace toml
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline value to_toml(T&& x)
|
|
||||||
{
|
|
||||||
return value(std::forward<T>(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline value to_toml(T&& x, string_t kind)
|
|
||||||
{
|
|
||||||
return value(std::forward<T>(x), kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline value to_toml(local_date d, local_time t)
|
|
||||||
{
|
|
||||||
return value(local_datetime(d, t));
|
|
||||||
}
|
|
||||||
inline value to_toml(local_date d, local_time t, time_offset ofs)
|
|
||||||
{
|
|
||||||
return value(offset_datetime(d, t, ofs));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ... Ts>
|
|
||||||
inline value to_toml(Ts&& ... xs)
|
|
||||||
{
|
|
||||||
return value(toml::array{toml::value(std::forward<Ts>(xs)) ... });
|
|
||||||
}
|
|
||||||
|
|
||||||
inline value to_toml(std::initializer_list<std::pair<std::string, toml::value>> xs)
|
|
||||||
{
|
|
||||||
return value(toml::table(xs.begin(), xs.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // toml
|
|
||||||
#endif // TOML11_TO_TOML
|
|
||||||
136
toml/traits.hpp
136
toml/traits.hpp
@@ -1,19 +1,27 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_TRAITS
|
#ifndef TOML11_TRAITS_HPP
|
||||||
#define TOML11_TRAITS
|
#define TOML11_TRAITS_HPP
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
#include <string>
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
#if __has_include(<string_view>)
|
||||||
|
#include <string_view>
|
||||||
|
#endif // has_include(<string_view>)
|
||||||
|
#endif // cplusplus >= C++17
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
template<typename C, template<typename ...> class T, template<typename ...> class A>
|
||||||
|
class basic_value;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
template<typename T>
|
// check whether type T is a kind of container/map class
|
||||||
using unwrap_t = typename std::decay<T>::type;
|
|
||||||
|
|
||||||
struct has_iterator_impl
|
struct has_iterator_impl
|
||||||
{
|
{
|
||||||
@@ -42,6 +50,32 @@ struct has_resize_method_impl
|
|||||||
template<typename T> static std::false_type check(...);
|
template<typename T> static std::false_type check(...);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct is_comparable_impl
|
||||||
|
{
|
||||||
|
template<typename T> static std::true_type check(decltype(std::declval<T>() < std::declval<T>())*);
|
||||||
|
template<typename T> static std::false_type check(...);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct has_from_toml_method_impl
|
||||||
|
{
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class Tb, template<typename ...> class A>
|
||||||
|
static std::true_type check(
|
||||||
|
decltype(std::declval<T>().from_toml(
|
||||||
|
std::declval<::toml::basic_value<C, Tb, A>>()))*);
|
||||||
|
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class Tb, template<typename ...> class A>
|
||||||
|
static std::false_type check(...);
|
||||||
|
};
|
||||||
|
struct has_into_toml_method_impl
|
||||||
|
{
|
||||||
|
template<typename T>
|
||||||
|
static std::true_type check(decltype(std::declval<T>().into_toml())*);
|
||||||
|
template<typename T>
|
||||||
|
static std::false_type check(...);
|
||||||
|
};
|
||||||
|
|
||||||
/// Intel C++ compiler can not use decltype in parent class declaration, here
|
/// Intel C++ compiler can not use decltype in parent class declaration, here
|
||||||
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
|
/// is a hack to work around it. https://stackoverflow.com/a/23953090/4692076
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
@@ -58,11 +92,25 @@ template<typename T>
|
|||||||
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
|
struct has_mapped_type : decltype(has_mapped_type_impl::check<T>(nullptr)){};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){};
|
struct has_resize_method : decltype(has_resize_method_impl::check<T>(nullptr)){};
|
||||||
|
template<typename T>
|
||||||
|
struct is_comparable : decltype(is_comparable_impl::check<T>(nullptr)){};
|
||||||
|
|
||||||
|
template<typename T, typename C,
|
||||||
|
template<typename ...> class Tb, template<typename ...> class A>
|
||||||
|
struct has_from_toml_method
|
||||||
|
: decltype(has_from_toml_method_impl::check<T, C, Tb, A>(nullptr)){};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct has_into_toml_method
|
||||||
|
: decltype(has_into_toml_method_impl::check<T>(nullptr)){};
|
||||||
|
|
||||||
#ifdef __INTEL_COMPILER
|
#ifdef __INTEL_COMPILER
|
||||||
#undef decltype(...)
|
#undef decltype(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// C++17 and/or/not
|
||||||
|
|
||||||
template<typename ...> struct conjunction : std::true_type{};
|
template<typename ...> struct conjunction : std::true_type{};
|
||||||
template<typename T> struct conjunction<T> : T{};
|
template<typename T> struct conjunction<T> : T{};
|
||||||
template<typename T, typename ... Ts>
|
template<typename T, typename ... Ts>
|
||||||
@@ -80,6 +128,9 @@ struct disjunction<T, Ts...> :
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
|
struct negation : std::integral_constant<bool, !static_cast<bool>(T::value)>{};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// type checkers
|
||||||
|
|
||||||
template<typename T> struct is_std_pair : std::false_type{};
|
template<typename T> struct is_std_pair : std::false_type{};
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
|
struct is_std_pair<std::pair<T1, T2>> : std::true_type{};
|
||||||
@@ -92,7 +143,45 @@ template<typename T> struct is_chrono_duration: std::false_type{};
|
|||||||
template<typename Rep, typename Period>
|
template<typename Rep, typename Period>
|
||||||
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};
|
struct is_chrono_duration<std::chrono::duration<Rep, Period>>: std::true_type{};
|
||||||
|
|
||||||
// to use toml::get<std::tuple<T1, T2, ...>> in C++11
|
template<typename T>
|
||||||
|
struct is_map : conjunction< // map satisfies all the following conditions
|
||||||
|
has_iterator<T>, // has T::iterator
|
||||||
|
has_value_type<T>, // has T::value_type
|
||||||
|
has_key_type<T>, // has T::key_type
|
||||||
|
has_mapped_type<T> // has T::mapped_type
|
||||||
|
>{};
|
||||||
|
template<typename T> struct is_map<T&> : is_map<T>{};
|
||||||
|
template<typename T> struct is_map<T const&> : is_map<T>{};
|
||||||
|
template<typename T> struct is_map<T volatile&> : is_map<T>{};
|
||||||
|
template<typename T> struct is_map<T const volatile&> : is_map<T>{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_container : conjunction<
|
||||||
|
negation<is_map<T>>, // not a map
|
||||||
|
negation<std::is_same<T, std::string>>, // not a std::string
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
negation<std::is_same<T, std::string_view>>, // not a std::string_view
|
||||||
|
#endif
|
||||||
|
has_iterator<T>, // has T::iterator
|
||||||
|
has_value_type<T> // has T::value_type
|
||||||
|
>{};
|
||||||
|
template<typename T> struct is_container<T&> : is_container<T>{};
|
||||||
|
template<typename T> struct is_container<T const&> : is_container<T>{};
|
||||||
|
template<typename T> struct is_container<T volatile&> : is_container<T>{};
|
||||||
|
template<typename T> struct is_container<T const volatile&> : is_container<T>{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_basic_value: std::false_type{};
|
||||||
|
template<typename T> struct is_basic_value<T&> : is_basic_value<T>{};
|
||||||
|
template<typename T> struct is_basic_value<T const&> : is_basic_value<T>{};
|
||||||
|
template<typename T> struct is_basic_value<T volatile&> : is_basic_value<T>{};
|
||||||
|
template<typename T> struct is_basic_value<T const volatile&> : is_basic_value<T>{};
|
||||||
|
template<typename C, template<typename ...> class M, template<typename ...> class V>
|
||||||
|
struct is_basic_value<::toml::basic_value<C, M, V>>: std::true_type{};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// C++14 index_sequence
|
||||||
|
|
||||||
template<std::size_t ... Ns> struct index_sequence{};
|
template<std::size_t ... Ns> struct index_sequence{};
|
||||||
|
|
||||||
template<typename IS, std::size_t N> struct push_back_index_sequence{};
|
template<typename IS, std::size_t N> struct push_back_index_sequence{};
|
||||||
@@ -116,6 +205,41 @@ struct index_sequence_maker<0>
|
|||||||
template<std::size_t N>
|
template<std::size_t N>
|
||||||
using make_index_sequence = typename index_sequence_maker<N-1>::type;
|
using make_index_sequence = typename index_sequence_maker<N-1>::type;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// C++14 enable_if_t
|
||||||
|
template<bool B, typename T>
|
||||||
|
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// return_type_of_t
|
||||||
|
|
||||||
|
#if __cplusplus >= 201703L
|
||||||
|
|
||||||
|
template<typename F, typename ... Args>
|
||||||
|
using return_type_of_t = std::invoke_result_t<F, Args...>;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// result_of is deprecated after C++17
|
||||||
|
template<typename F, typename ... Args>
|
||||||
|
using return_type_of_t = typename std::result_of<F(Args...)>::type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// is_string_literal
|
||||||
|
//
|
||||||
|
// to use this, pass `typename remove_reference<T>::type` to T.
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct is_string_literal:
|
||||||
|
disjunction<
|
||||||
|
std::is_same<const char*, T>,
|
||||||
|
conjunction<
|
||||||
|
std::is_array<T>,
|
||||||
|
std::is_same<const char, typename std::remove_extent<T>::type>
|
||||||
|
>
|
||||||
|
>{};
|
||||||
|
|
||||||
}// detail
|
}// detail
|
||||||
}//toml
|
}//toml
|
||||||
#endif // TOML_TRAITS
|
#endif // TOML_TRAITS
|
||||||
|
|||||||
248
toml/types.hpp
248
toml/types.hpp
@@ -1,54 +1,55 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_TYPES_H
|
#ifndef TOML11_TYPES_HPP
|
||||||
#define TOML11_TYPES_H
|
#define TOML11_TYPES_HPP
|
||||||
#include "datetime.hpp"
|
#include "datetime.hpp"
|
||||||
#include "string.hpp"
|
#include "string.hpp"
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
|
#include "comments.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
using character = char;
|
template<typename Comment, // discard/preserve_comment
|
||||||
|
template<typename ...> class Table, // map-like class
|
||||||
|
template<typename ...> class Array> // vector-like class
|
||||||
|
class basic_value;
|
||||||
|
|
||||||
class value;
|
using character = char;
|
||||||
using key = std::string;
|
using key = std::string;
|
||||||
|
|
||||||
using Boolean = bool;
|
using boolean = bool;
|
||||||
using Integer = std::int64_t;
|
using integer = std::int64_t;
|
||||||
using Float = double;
|
using floating = double; // "float" is a keyward, cannot use it here.
|
||||||
using String = ::toml::string;
|
// the following stuffs are structs defined here, so aliases are not needed.
|
||||||
using Datetime = offset_datetime;
|
// - string
|
||||||
using OffsetDatetime = offset_datetime;
|
// - offset_datetime
|
||||||
using LocalDatetime = local_datetime;
|
// - offset_datetime
|
||||||
using LocalDate = local_date;
|
// - local_datetime
|
||||||
using LocalTime = local_time;
|
// - local_date
|
||||||
using Array = std::vector<value>;
|
// - local_time
|
||||||
using Table = std::unordered_map<key, value>;
|
|
||||||
|
|
||||||
// alias for snake_case, consistency with STL/Boost, toml::key, toml::value
|
// default toml::value and default array/table. these are defined after defining
|
||||||
using boolean = Boolean;
|
// basic_value itself.
|
||||||
using integer = Integer;
|
// using value = basic_value<discard_comments, std::unordered_map, std::vector>;
|
||||||
using floating = Float; // XXX `float` is keyword. we can't use it here
|
// using array = typename value::array_type;
|
||||||
using array = Array;
|
// using table = typename value::table_type;
|
||||||
using table = Table;
|
|
||||||
|
|
||||||
enum class value_t : std::uint8_t
|
enum class value_t : std::uint8_t
|
||||||
{
|
{
|
||||||
Empty = 0,
|
empty = 0,
|
||||||
Boolean = 1,
|
boolean = 1,
|
||||||
Integer = 2,
|
integer = 2,
|
||||||
Float = 3,
|
floating = 3,
|
||||||
String = 4,
|
string = 4,
|
||||||
OffsetDatetime = 5,
|
offset_datetime = 5,
|
||||||
LocalDatetime = 6,
|
local_datetime = 6,
|
||||||
LocalDate = 7,
|
local_date = 7,
|
||||||
LocalTime = 8,
|
local_time = 8,
|
||||||
Array = 9,
|
array = 9,
|
||||||
Table = 10,
|
table = 10,
|
||||||
Unknown = 255,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename charT, typename traits>
|
template<typename charT, typename traits>
|
||||||
@@ -57,27 +58,27 @@ operator<<(std::basic_ostream<charT, traits>& os, value_t t)
|
|||||||
{
|
{
|
||||||
switch(t)
|
switch(t)
|
||||||
{
|
{
|
||||||
case toml::value_t::Boolean : os << "boolean"; return os;
|
case value_t::boolean : os << "boolean"; return os;
|
||||||
case toml::value_t::Integer : os << "integer"; return os;
|
case value_t::integer : os << "integer"; return os;
|
||||||
case toml::value_t::Float : os << "float"; return os;
|
case value_t::floating : os << "floating"; return os;
|
||||||
case toml::value_t::String : os << "string"; return os;
|
case value_t::string : os << "string"; return os;
|
||||||
case toml::value_t::OffsetDatetime: os << "offset_datetime"; return os;
|
case value_t::offset_datetime : os << "offset_datetime"; return os;
|
||||||
case toml::value_t::LocalDatetime : os << "local_datetime"; return os;
|
case value_t::local_datetime : os << "local_datetime"; return os;
|
||||||
case toml::value_t::LocalDate : os << "local_date"; return os;
|
case value_t::local_date : os << "local_date"; return os;
|
||||||
case toml::value_t::LocalTime : os << "local_time"; return os;
|
case value_t::local_time : os << "local_time"; return os;
|
||||||
case toml::value_t::Array : os << "array"; return os;
|
case value_t::array : os << "array"; return os;
|
||||||
case toml::value_t::Table : os << "table"; return os;
|
case value_t::table : os << "table"; return os;
|
||||||
case toml::value_t::Empty : os << "empty"; return os;
|
case value_t::empty : os << "empty"; return os;
|
||||||
case toml::value_t::Unknown : os << "unknown"; return os;
|
default : os << "unknown"; return os;
|
||||||
default : os << "nothing"; return os;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename charT = character, typename traits = std::char_traits<charT>,
|
template<typename charT = char,
|
||||||
|
typename traits = std::char_traits<charT>,
|
||||||
typename alloc = std::allocator<charT>>
|
typename alloc = std::allocator<charT>>
|
||||||
inline std::basic_string<charT, traits, alloc> stringize(value_t t)
|
inline std::basic_string<charT, traits, alloc> stringize(value_t t)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::basic_ostringstream<charT, traits, alloc> oss;
|
||||||
oss << t;
|
oss << t;
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
@@ -85,112 +86,63 @@ inline std::basic_string<charT, traits, alloc> stringize(value_t t)
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename T>
|
// helper to define a type that represents a value_t value.
|
||||||
constexpr inline value_t check_type()
|
template<value_t V>
|
||||||
{
|
using value_t_constant = std::integral_constant<value_t, V>;
|
||||||
using type = typename std::remove_cv<
|
|
||||||
typename std::remove_reference<T>::type
|
|
||||||
>::type;
|
|
||||||
return std::is_same<type, toml::boolean>::value ? value_t::Boolean :
|
|
||||||
std::is_integral<type>::value ? value_t::Integer :
|
|
||||||
std::is_floating_point<type>::value ? value_t::Float :
|
|
||||||
std::is_same<type, std::string>::value ? value_t::String :
|
|
||||||
std::is_same<type, toml::string>::value ? value_t::String :
|
|
||||||
std::is_same<type, toml::local_date>::value ? value_t::LocalDate :
|
|
||||||
std::is_same<type, toml::local_time>::value ? value_t::LocalTime :
|
|
||||||
is_chrono_duration<type>::value ? value_t::LocalTime :
|
|
||||||
std::is_same<type, toml::local_datetime>::value ? value_t::LocalDatetime :
|
|
||||||
std::is_same<type, toml::offset_datetime>::value ? value_t::OffsetDatetime :
|
|
||||||
std::is_same<type, std::chrono::system_clock::time_point>::value ? value_t::OffsetDatetime :
|
|
||||||
std::is_convertible<type, toml::array>::value ? value_t::Array :
|
|
||||||
std::is_convertible<type, toml::table>::value ? value_t::Table :
|
|
||||||
value_t::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline bool is_valid(value_t vt)
|
// meta-function that convertes from value_t to the exact toml type that corresponds to.
|
||||||
{
|
// It takes toml::basic_value type because array and table types depend on it.
|
||||||
return vt != value_t::Unknown;
|
template<value_t t, typename Value> struct enum_to_type {using type = void ;};
|
||||||
}
|
template<typename Value> struct enum_to_type<value_t::empty , Value>{using type = void ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::boolean , Value>{using type = boolean ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::integer , Value>{using type = integer ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::floating , Value>{using type = floating ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::string , Value>{using type = string ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::offset_datetime, Value>{using type = offset_datetime ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::local_datetime , Value>{using type = local_datetime ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::local_date , Value>{using type = local_date ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::local_time , Value>{using type = local_time ;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::array , Value>{using type = typename Value::array_type;};
|
||||||
|
template<typename Value> struct enum_to_type<value_t::table , Value>{using type = typename Value::table_type;};
|
||||||
|
|
||||||
template<value_t t> struct toml_default_type;
|
// meta-function that converts from an exact toml type to the enum that corresponds to.
|
||||||
template<> struct toml_default_type<value_t::Boolean > {typedef boolean type;};
|
template<typename T, typename Value>
|
||||||
template<> struct toml_default_type<value_t::Integer > {typedef integer type;};
|
struct type_to_enum : std::conditional<
|
||||||
template<> struct toml_default_type<value_t::Float > {typedef floating type;};
|
std::is_same<T, typename Value::array_type>::value, // if T == array_type,
|
||||||
template<> struct toml_default_type<value_t::String > {typedef string type;};
|
value_t_constant<value_t::array>, // then value_t::array
|
||||||
template<> struct toml_default_type<value_t::OffsetDatetime>{typedef offset_datetime type;};
|
typename std::conditional< // else...
|
||||||
template<> struct toml_default_type<value_t::LocalDatetime> {typedef local_datetime type;};
|
std::is_same<T, typename Value::table_type>::value, // if T == table_type
|
||||||
template<> struct toml_default_type<value_t::LocalDate> {typedef local_date type;};
|
value_t_constant<value_t::table>, // then value_t::table
|
||||||
template<> struct toml_default_type<value_t::LocalTime> {typedef local_time type;};
|
value_t_constant<value_t::empty> // else value_t::empty
|
||||||
template<> struct toml_default_type<value_t::Array > {typedef array type;};
|
>::type
|
||||||
template<> struct toml_default_type<value_t::Table > {typedef table type;};
|
>::type {};
|
||||||
template<> struct toml_default_type<value_t::Empty > {typedef void type;};
|
template<typename Value> struct type_to_enum<boolean , Value>: value_t_constant<value_t::boolean > {};
|
||||||
template<> struct toml_default_type<value_t::Unknown > {typedef void type;};
|
template<typename Value> struct type_to_enum<integer , Value>: value_t_constant<value_t::integer > {};
|
||||||
|
template<typename Value> struct type_to_enum<floating , Value>: value_t_constant<value_t::floating > {};
|
||||||
|
template<typename Value> struct type_to_enum<string , Value>: value_t_constant<value_t::string > {};
|
||||||
|
template<typename Value> struct type_to_enum<offset_datetime, Value>: value_t_constant<value_t::offset_datetime> {};
|
||||||
|
template<typename Value> struct type_to_enum<local_datetime , Value>: value_t_constant<value_t::local_datetime > {};
|
||||||
|
template<typename Value> struct type_to_enum<local_date , Value>: value_t_constant<value_t::local_date > {};
|
||||||
|
template<typename Value> struct type_to_enum<local_time , Value>: value_t_constant<value_t::local_time > {};
|
||||||
|
|
||||||
template<typename T> struct toml_value_t {static constexpr value_t value = value_t::Unknown ;};
|
// meta-function that checks the type T is the same as one of the toml::* types.
|
||||||
template<> struct toml_value_t<Boolean >{static constexpr value_t value = value_t::Boolean ;};
|
template<typename T, typename Value>
|
||||||
template<> struct toml_value_t<Integer >{static constexpr value_t value = value_t::Integer ;};
|
|
||||||
template<> struct toml_value_t<Float >{static constexpr value_t value = value_t::Float ;};
|
|
||||||
template<> struct toml_value_t<String >{static constexpr value_t value = value_t::String ;};
|
|
||||||
template<> struct toml_value_t<OffsetDatetime>{static constexpr value_t value = value_t::OffsetDatetime;};
|
|
||||||
template<> struct toml_value_t<LocalDatetime >{static constexpr value_t value = value_t::LocalDatetime ;};
|
|
||||||
template<> struct toml_value_t<LocalDate >{static constexpr value_t value = value_t::LocalDate ;};
|
|
||||||
template<> struct toml_value_t<LocalTime >{static constexpr value_t value = value_t::LocalTime ;};
|
|
||||||
template<> struct toml_value_t<Array >{static constexpr value_t value = value_t::Array ;};
|
|
||||||
template<> struct toml_value_t<Table >{static constexpr value_t value = value_t::Table ;};
|
|
||||||
template<typename T> constexpr value_t toml_value_t<T>::value;
|
|
||||||
constexpr value_t toml_value_t<Boolean >::value;
|
|
||||||
constexpr value_t toml_value_t<Integer >::value;
|
|
||||||
constexpr value_t toml_value_t<Float >::value;
|
|
||||||
constexpr value_t toml_value_t<String >::value;
|
|
||||||
constexpr value_t toml_value_t<OffsetDatetime>::value;
|
|
||||||
constexpr value_t toml_value_t<LocalDatetime >::value;
|
|
||||||
constexpr value_t toml_value_t<LocalDate >::value;
|
|
||||||
constexpr value_t toml_value_t<LocalTime >::value;
|
|
||||||
constexpr value_t toml_value_t<Array >::value;
|
|
||||||
constexpr value_t toml_value_t<Table >::value;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_exact_toml_type : disjunction<
|
struct is_exact_toml_type : disjunction<
|
||||||
std::is_same<T, Boolean >,
|
std::is_same<T, boolean >,
|
||||||
std::is_same<T, Integer >,
|
std::is_same<T, integer >,
|
||||||
std::is_same<T, Float >,
|
std::is_same<T, floating >,
|
||||||
std::is_same<T, String >,
|
std::is_same<T, string >,
|
||||||
std::is_same<T, offset_datetime>,
|
std::is_same<T, offset_datetime>,
|
||||||
std::is_same<T, local_datetime>,
|
std::is_same<T, local_datetime >,
|
||||||
std::is_same<T, local_date>,
|
std::is_same<T, local_date >,
|
||||||
std::is_same<T, local_time>,
|
std::is_same<T, local_time >,
|
||||||
std::is_same<T, Array >,
|
std::is_same<T, typename Value::array_type>,
|
||||||
std::is_same<T, Table >
|
std::is_same<T, typename Value::table_type>
|
||||||
>{};
|
>{};
|
||||||
template<typename T> struct is_exact_toml_type<T&> : is_exact_toml_type<T>{};
|
template<typename T, typename V> struct is_exact_toml_type<T&, V> : is_exact_toml_type<T, V>{};
|
||||||
template<typename T> struct is_exact_toml_type<T const&> : is_exact_toml_type<T>{};
|
template<typename T, typename V> struct is_exact_toml_type<T const&, V> : is_exact_toml_type<T, V>{};
|
||||||
template<typename T> struct is_exact_toml_type<T volatile&> : is_exact_toml_type<T>{};
|
template<typename T, typename V> struct is_exact_toml_type<T volatile&, V> : is_exact_toml_type<T, V>{};
|
||||||
template<typename T> struct is_exact_toml_type<T const volatile&>: is_exact_toml_type<T>{};
|
template<typename T, typename V> struct is_exact_toml_type<T const volatile&, V>: is_exact_toml_type<T, V>{};
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_map : conjunction<
|
|
||||||
has_iterator<T>,
|
|
||||||
has_value_type<T>,
|
|
||||||
has_key_type<T>,
|
|
||||||
has_mapped_type<T>
|
|
||||||
>{};
|
|
||||||
template<typename T> struct is_map<T&> : is_map<T>{};
|
|
||||||
template<typename T> struct is_map<T const&> : is_map<T>{};
|
|
||||||
template<typename T> struct is_map<T volatile&> : is_map<T>{};
|
|
||||||
template<typename T> struct is_map<T const volatile&> : is_map<T>{};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_container : conjunction<
|
|
||||||
negation<is_map<T>>,
|
|
||||||
negation<std::is_same<T, std::string>>,
|
|
||||||
has_iterator<T>,
|
|
||||||
has_value_type<T>
|
|
||||||
>{};
|
|
||||||
template<typename T> struct is_container<T&> : is_container<T>{};
|
|
||||||
template<typename T> struct is_container<T const&> : is_container<T>{};
|
|
||||||
template<typename T> struct is_container<T volatile&> : is_container<T>{};
|
|
||||||
template<typename T> struct is_container<T const volatile&> : is_container<T>{};
|
|
||||||
|
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
} // toml
|
} // toml
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
// Copyright Toru Niina 2017.
|
// Copyright Toru Niina 2017.
|
||||||
// Distributed under the MIT License.
|
// Distributed under the MIT License.
|
||||||
#ifndef TOML11_UTILITY
|
#ifndef TOML11_UTILITY_HPP
|
||||||
#define TOML11_UTILITY
|
#define TOML11_UTILITY_HPP
|
||||||
#include "traits.hpp"
|
#include "traits.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#if __cplusplus >= 201402L
|
||||||
|
# define TOML11_MARK_AS_DEPRECATED(msg) [[deprecated(msg)]]
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
# define TOML11_MARK_AS_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define TOML11_MARK_AS_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||||
|
#else
|
||||||
|
# define TOML11_MARK_AS_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace toml
|
namespace toml
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -29,8 +39,9 @@ inline void resize_impl(T& container, std::size_t N, std::true_type)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline void resize_impl(T& container, std::size_t N, std::false_type)
|
inline void resize_impl(T& container, std::size_t N, std::false_type)
|
||||||
{
|
{
|
||||||
if(container.size() >= N) return;
|
if(container.size() >= N) {return;}
|
||||||
else throw std::invalid_argument("not resizable type");
|
|
||||||
|
throw std::invalid_argument("not resizable type");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // detail
|
} // detail
|
||||||
@@ -38,8 +49,9 @@ inline void resize_impl(T& container, std::size_t N, std::false_type)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline void resize(T& container, std::size_t N)
|
inline void resize(T& container, std::size_t N)
|
||||||
{
|
{
|
||||||
if(container.size() == N) return;
|
if(container.size() == N) {return;}
|
||||||
else return detail::resize_impl(container, N, detail::has_resize_method<T>());
|
|
||||||
|
return detail::resize_impl(container, N, detail::has_resize_method<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -67,13 +79,11 @@ std::string concat_to_string(Ts&& ... args)
|
|||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
T from_string(const std::string& str, U&& opt)
|
T from_string(const std::string& str, U&& opt)
|
||||||
{
|
{
|
||||||
T v(std::forward<U>(opt));
|
T v(static_cast<T>(std::forward<U>(opt)));
|
||||||
std::istringstream iss(str);
|
std::istringstream iss(str);
|
||||||
iss >> v;
|
iss >> v;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}// toml
|
}// toml
|
||||||
#endif // TOML11_UTILITY
|
#endif // TOML11_UTILITY
|
||||||
|
|||||||
1911
toml/value.hpp
1911
toml/value.hpp
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user