From 84b5749c6b118c8fafb4ab6f16d86b2e0b1f56c2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 13:23:26 +0900 Subject: [PATCH 001/162] feat: implement comment containers --- toml/comments.hpp | 369 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 toml/comments.hpp diff --git a/toml/comments.hpp b/toml/comments.hpp new file mode 100644 index 0000000..e5d88f5 --- /dev/null +++ b/toml/comments.hpp @@ -0,0 +1,369 @@ +// Copyright Toru Niina 2019. +// Distributed under the MIT License. +#ifndef TOML11_COMMENTS_HPP +#define TOML11_COMMENTS_HPP +#include +#include +#include +#include +#include +#include + +// This file provides mainly two classes, `preserve_comments` and `discard_comments`. +// Those two are a container that have the same interface as `std::vector` +// but bahaves in the opposite way. `preserve_comments` is just the same as +// `std::vector` 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 +{ + +// use it in the following way +// +// const toml::basic_value data = +// toml::parse("example.toml"); +// +// the interface is almost the same as std::vector. +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; + + 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& c): comments(c){} + explicit preserve_comments(std::vector&& c) + : comments(std::move(c)) + {} + + 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 x): comments(x) {} + template + preserve_comments(InputIterator first, InputIterator last) + : comments(first, last) + {} + + template + void assign(InputIterator first, InputIterator last) {comments.assign(first, last);} + void assign(std::initializer_list 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 + iterator insert(const_iterator p, InputIterator first, InputIterator last) + { + return comments.insert(p, first, last); + } + iterator insert(const_iterator p, std::initializer_list ini) + { + return comments.insert(p, ini); + } + + template + iterator emplace(const_iterator p, Ts&& ... args) + { + return comments.emplace(p, std::forward(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 + void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward(args)...);} + template + void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward(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 discard_comments& lhs, const discard_comments& rhs); + friend bool operator!=(const discard_comments& lhs, const discard_comments& rhs); + friend bool operator< (const discard_comments& lhs, const discard_comments& rhs); + friend bool operator<=(const discard_comments& lhs, const discard_comments& rhs); + friend bool operator> (const discard_comments& lhs, const discard_comments& rhs); + friend bool operator>=(const discard_comments& lhs, const discard_comments& rhs); + + private: + + container_type comments; +}; + +inline bool operator==(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments == rhs.comments;} +inline bool operator!=(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments != rhs.comments;} +inline bool operator< (const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments < rhs.comments;} +inline bool operator<=(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments <= rhs.comments;} +inline bool operator> (const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments > rhs.comments;} +inline bool operator>=(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments >= rhs.comments;} + +inline void swap(discard_comments& lhs, discard_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 +struct empty_iterator +{ + using value_type = T; + using reference_type = typename std::conditional::type; + using pointer_type = typename std::conditional::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 {return *pointer_type(nullptr);} + 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 +bool operator==(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} +template +bool operator!=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +template +bool operator< (const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +template +bool operator<=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} +template +bool operator> (const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +template +bool operator>=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} + +template +typename empty_iterator::difference_type +operator-(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return 0;} + +template +empty_iterator +operator+(typename empty_iterator::difference_type lhs, const empty_iterator& rhs) noexcept {return rhs;} +template +empty_iterator +operator+(const empty_iterator& lhs, typename empty_iterator::difference_type rhs) 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; + using const_iterator = detail::empty_iterator; + using reverse_iterator = detail::empty_iterator; + using const_reverse_iterator = detail::empty_iterator; + + 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&) noexcept {} + explicit discard_comments(std::vector&&) noexcept {} + + explicit discard_comments(size_type) noexcept {} + discard_comments(size_type, const std::string&) noexcept {} + discard_comments(std::initializer_list) noexcept {} + template + discard_comments(InputIterator, InputIterator) noexcept {} + + template + void assign(InputIterator, InputIterator) noexcept {} + void assign(std::initializer_list) 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 + iterator insert(const_iterator, InputIterator, InputIterator) {return iterator{};} + iterator insert(const_iterator, std::initializer_list) {return iterator{};} + + template + 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 + void emplace_back(Ts&& ...) {return;} + template + 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 From 2567f2a78795c2430e371d07c1bad5390f53d230 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 13:25:02 +0900 Subject: [PATCH 002/162] feat: add source_location for error message generation. --- toml/source_location.hpp | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 toml/source_location.hpp diff --git a/toml/source_location.hpp b/toml/source_location.hpp new file mode 100644 index 0000000..48396a0 --- /dev/null +++ b/toml/source_location.hpp @@ -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 + +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_ = std::stoul(reg->line_num()); + column_num_ = reg->before() + 1; + region_size_ = 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 From 8acc3481060e1dc1e30c3f2c7133514ded63dfde Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 13:33:57 +0900 Subject: [PATCH 003/162] feat: :boom: change interface around types - change value_t::typename from CamelCase to snake_case. - drop CamelCase typename supports. The changes are introduced to make the interfaces uniform. For some (historical) reasons, toml11 has both CamelCase names and snake_case names for types. Additionally, since `float` is a keyword, snake_case names uses `floating` to avoid collision and CamelCase name uses `Float` because toml official calls it `Float`. This is too confusing. Since it is a major upgrade, I think it is a big chance to make them uniform. --- toml/types.hpp | 191 ++++++++++++++++++++++--------------------------- 1 file changed, 85 insertions(+), 106 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index 47c9248..f283df8 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -5,50 +5,46 @@ #include "datetime.hpp" #include "string.hpp" #include "traits.hpp" -#include -#include +#include "comments.hpp" namespace toml { -using character = char; +template Table, // map-like class + template Array> // vector-like class +class basic_value; -class value; +using character = char; using key = std::string; -using Boolean = bool; -using Integer = std::int64_t; -using Float = double; -using String = ::toml::string; -using Datetime = offset_datetime; -using OffsetDatetime = offset_datetime; -using LocalDatetime = local_datetime; -using LocalDate = local_date; -using LocalTime = local_time; -using Array = std::vector; -using Table = std::unordered_map; +using boolean = bool; +using integer = std::int64_t; +using floating = double; // "float" is a keyward, cannot use it here. +// the following stuffs are structs defined here, so aliases are not needed. +// - string +// - offset_datetime +// - offset_datetime +// - local_datetime +// - local_date +// - local_time -// alias for snake_case, consistency with STL/Boost, toml::key, toml::value -using boolean = Boolean; -using integer = Integer; -using floating = Float; // XXX `float` is keyword. we can't use it here -using array = Array; -using table = Table; +// default toml::value and default array/table +using value = basic_value; enum class value_t : std::uint8_t { - Empty = 0, - Boolean = 1, - Integer = 2, - Float = 3, - String = 4, - OffsetDatetime = 5, - LocalDatetime = 6, - LocalDate = 7, - LocalTime = 8, - Array = 9, - Table = 10, - Unknown = 255, + empty = 0, + boolean = 1, + integer = 2, + floating = 3, + string = 4, + offset_datetime = 5, + local_datetime = 6, + local_date = 7, + local_time = 8, + array = 9, + table = 10, }; template @@ -57,27 +53,27 @@ operator<<(std::basic_ostream& os, value_t t) { switch(t) { - case toml::value_t::Boolean : os << "boolean"; return os; - case toml::value_t::Integer : os << "integer"; return os; - case toml::value_t::Float : os << "float"; return os; - case toml::value_t::String : os << "string"; return os; - case toml::value_t::OffsetDatetime: os << "offset_datetime"; return os; - case toml::value_t::LocalDatetime : os << "local_datetime"; return os; - case toml::value_t::LocalDate : os << "local_date"; return os; - case toml::value_t::LocalTime : os << "local_time"; return os; - case toml::value_t::Array : os << "array"; return os; - case toml::value_t::Table : os << "table"; return os; - case toml::value_t::Empty : os << "empty"; return os; - case toml::value_t::Unknown : os << "unknown"; return os; - default : os << "nothing"; return os; + case value_t::boolean : os << "boolean"; return os; + case value_t::integer : os << "integer"; return os; + case value_t::floating : os << "floating"; return os; + case value_t::string : os << "string"; return os; + case value_t::offset_datetime : os << "offset_datetime"; return os; + case value_t::local_datetime : os << "local_datetime"; return os; + case value_t::local_date : os << "local_date"; return os; + case value_t::local_time : os << "local_time"; return os; + case value_t::array : os << "array"; return os; + case value_t::table : os << "table"; return os; + case value_t::empty : os << "empty"; return os; + default : os << "unknown"; return os; } } -template, +template, typename alloc = std::allocator> inline std::basic_string stringize(value_t t) { - std::ostringstream oss; + std::basic_ostringstream oss; oss << t; return oss.str(); } @@ -85,60 +81,43 @@ inline std::basic_string stringize(value_t t) namespace detail { -template -constexpr inline value_t check_type() -{ - using type = typename std::remove_cv< - typename std::remove_reference::type - >::type; - return std::is_same::value ? value_t::Boolean : - std::is_integral::value ? value_t::Integer : - std::is_floating_point::value ? value_t::Float : - std::is_same::value ? value_t::String : - std::is_same::value ? value_t::String : - std::is_same::value ? value_t::LocalDate : - std::is_same::value ? value_t::LocalTime : - is_chrono_duration::value ? value_t::LocalTime : - std::is_same::value ? value_t::LocalDatetime : - std::is_same::value ? value_t::OffsetDatetime : - std::is_same::value ? value_t::OffsetDatetime : - std::is_convertible::value ? value_t::Array : - std::is_convertible::value ? value_t::Table : - value_t::Unknown; -} +// 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. +template struct enum_to_type {using type = void ;}; +template struct enum_to_type{using type = void ;}; +template struct enum_to_type{using type = boolean ;}; +template struct enum_to_type{using type = integer ;}; +template struct enum_to_type{using type = floating ;}; +template struct enum_to_type{using type = string ;}; +template struct enum_to_type{using type = offset_datetime ;}; +template struct enum_to_type{using type = local_datetime ;}; +template struct enum_to_type{using type = local_date ;}; +template struct enum_to_type{using type = local_time ;}; +template struct enum_to_type{using type = typename Value::array_type;}; +template struct enum_to_type{using type = typename Value::table_type;}; -constexpr inline bool is_valid(value_t vt) -{ - return vt != value_t::Unknown; -} +// meta-function that converts from an exact toml type to the enum that corresponds to. +template +struct type_to_enum : typename std::conditional< + std::is_same::value, // if T == array_type, + std::integral_constant, // then value_t::array + typename std::conditional< // else... + std::is_same::value, // if T == table_type + std::integral_constant, // then value_t::table + std::integral_constant // else value_t::empty + >::type + >::type {} +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: std::integral_constant {}; -template struct toml_default_type; -template<> struct toml_default_type {typedef boolean type;}; -template<> struct toml_default_type {typedef integer type;}; -template<> struct toml_default_type {typedef floating type;}; -template<> struct toml_default_type {typedef string type;}; -template<> struct toml_default_type{typedef offset_datetime type;}; -template<> struct toml_default_type {typedef local_datetime type;}; -template<> struct toml_default_type {typedef local_date type;}; -template<> struct toml_default_type {typedef local_time type;}; -template<> struct toml_default_type {typedef array type;}; -template<> struct toml_default_type {typedef table type;}; -template<> struct toml_default_type {typedef void type;}; -template<> struct toml_default_type {typedef void type;}; - -template struct toml_value_t {static constexpr value_t value = value_t::Unknown ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::Boolean ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::Integer ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::Float ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::String ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::OffsetDatetime;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::LocalDatetime ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::LocalDate ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::LocalTime ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::Array ;}; -template<> struct toml_value_t{static constexpr value_t value = value_t::Table ;}; - -template +// meta-function that checks the type T is the same as one of the toml::* types. +template struct is_exact_toml_type : disjunction< std::is_same, std::is_same, @@ -148,13 +127,13 @@ struct is_exact_toml_type : disjunction< std::is_same, std::is_same, std::is_same, - std::is_same, - std::is_same + std::is_same, + std::is_same >{}; -template struct is_exact_toml_type : is_exact_toml_type{}; -template struct is_exact_toml_type : is_exact_toml_type{}; -template struct is_exact_toml_type : is_exact_toml_type{}; -template struct is_exact_toml_type: is_exact_toml_type{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type : is_exact_toml_type{}; +template struct is_exact_toml_type: is_exact_toml_type{}; } // detail } // toml From eaa3604dce24f1e47de2ddb346d0a338279d05c1 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 16:01:48 +0900 Subject: [PATCH 004/162] refactor: introduce value_t_constant as an alias for integral_constant --- toml/types.hpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index f283df8..f15e955 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -81,6 +81,10 @@ inline std::basic_string stringize(value_t t) namespace detail { +// helper to define a type that represents a value_t value. +template +using value_t_constant = std::integral_constant; + // 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. template struct enum_to_type {using type = void ;}; @@ -100,21 +104,21 @@ template struct enum_to_type{us template struct type_to_enum : typename std::conditional< std::is_same::value, // if T == array_type, - std::integral_constant, // then value_t::array + value_t_constant, // then value_t::array typename std::conditional< // else... std::is_same::value, // if T == table_type - std::integral_constant, // then value_t::table - std::integral_constant // else value_t::empty + value_t_constant, // then value_t::table + value_t_constant // else value_t::empty >::type >::type {} -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; -template struct type_to_enum: std::integral_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; +template struct type_to_enum: value_t_constant {}; // meta-function that checks the type T is the same as one of the toml::* types. template From b8d3038d383a4caf93df054badf70181f4e8447c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 16:03:26 +0900 Subject: [PATCH 005/162] feat: add meta function to detect conversions --- toml/types.hpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/toml/types.hpp b/toml/types.hpp index f15e955..2c0d9d8 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -139,6 +139,59 @@ template struct is_exact_toml_type template struct is_exact_toml_type : is_exact_toml_type{}; template struct is_exact_toml_type: is_exact_toml_type{}; +// meta-function that check type T is convertible to toml::* types +template +struct is_convertible_to_toml_value : disjunction< + std::is_same, // T is bool or + std::is_integral, // T is an integer or + std::is_floating_point, // T is a floating point or + std::is_same, // T is std::string or + std::is_same, // T is toml::string or + is_string_literal, // T is "string literal" or + std::is_same, // T is local_date or + std::is_same, // T is local_time or + std::is_same, // T is local_datetime or + std::is_same, // T is offset_datetime or + std::is_same // T is time_point or + is_chrono_duration, // T is a duration or + std::is_same, // T is an array type or + std::is_same, // T is an array type or + >{} + +// meta-function that returns value_t that represent the convertible type +template +struct convertible_toml_type_of : typename std::conditional< + /* if */ is_exact_toml_type::value, + /* then */ value_t_constant::value>, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ std::is_integral::value, + /* then */ value_t_constant, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ std::is_floating_point::value, + /* then */ value_t_constant, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ std::is_same::value, + /* then */ value_t_constant, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ is_string_literal, + /* then */ value_t_constant, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ is_chrono_duration, + /* then */ value_t_constant, + /* else */ typename std::conditional< + // ---------------------------------------------------------------------- + /* if */ std::is_same, + /* then */ value_t_constant, + /* else */ value_t_constant, + // ---------------------------------------------------------------------- + >::type>::type>::type>::type>::type>::type>::type + >{} + } // detail } // toml #endif// TOML11_TYPES_H From f04c97b587dc4877fc2acdb7eca89cb7f5db8f51 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 19:06:08 +0900 Subject: [PATCH 006/162] refactor: simplify format_underline a bit --- toml/region.hpp | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 7b4c006..2fb1eaa 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -383,17 +383,11 @@ struct region final : public region_base // to show a better error message. inline std::string format_underline(const std::string& message, - std::vector> reg_com, - std::vector helps = {}) + const std::vector>& reg_com, + const std::vector& helps = {}) { assert(!reg_com.empty()); -#ifdef _WIN32 - const auto newline = "\r\n"; -#else - const char newline = '\n'; -#endif - const auto line_num_width = std::max_element(reg_com.begin(), reg_com.end(), [](std::pair const& lhs, std::pair const& rhs) @@ -403,26 +397,26 @@ inline std::string format_underline(const std::string& message, )->first->line_num().size(); std::ostringstream retval; - retval << message << newline; + retval << message << '\n'; - for(std::size_t i=0; iname() == reg_com.at(i).first->name()) + // if the filenames are the same, print "..." + if(iter != reg_com.begin() && + std::prev(iter)->first->name() == iter->first->name()) { - retval << newline << " ..." << newline; + retval << "\n ...\n"; } - else + else // if filename differs, print " --> filename.toml" { - if(i != 0) {retval << newline;} - retval << " --> " << reg_com.at(i).first->name() << newline; + if(iter != reg_com.begin()) {retval << '\n';} + retval << " --> " << iter->first->name() << '\n'; } - - const region_base* const reg = reg_com.at(i).first; - const std::string& comment = reg_com.at(i).second; - + 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() << newline; + retval << " | " << reg->line() << '\n'; retval << make_string(line_num_width + 1, ' '); retval << " | " << make_string(reg->before(), ' '); @@ -440,20 +434,18 @@ inline std::string format_underline(const std::string& message, const auto underline_len = std::min(reg->size(), reg->line().size()); retval << make_string(underline_len, '~'); } - retval << ' '; retval << comment; } - if(helps.size() != 0) + if(!helps.empty()) { - retval << newline; + retval << '\n'; retval << make_string(line_num_width + 1, ' '); retval << " | "; for(const auto help : helps) { - retval << newline; - retval << "Hint: "; + retval << "\nHint: "; retval << help; } } From 14ad8d05568a1dc1543b16aad4e4cf8c91d9bf04 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 19:43:15 +0900 Subject: [PATCH 007/162] fix: fix typos and invalid names --- toml/comments.hpp | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/toml/comments.hpp b/toml/comments.hpp index e5d88f5..ef67de4 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -105,8 +105,6 @@ struct preserve_comments void push_back(std::string&& v) {comments.push_back(std::move(v));} void pop_back() {comments.pop_back();} - template - void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward(args)...);} template void emplace_back(Ts&& ... args) {comments.emplace_back(std::forward(args)...);} @@ -148,26 +146,26 @@ struct preserve_comments const_reverse_iterator crbegin() const noexcept {return comments.crbegin();} const_reverse_iterator crend() const noexcept {return comments.crend();} - friend bool operator==(const discard_comments& lhs, const discard_comments& rhs); - friend bool operator!=(const discard_comments& lhs, const discard_comments& rhs); - friend bool operator< (const discard_comments& lhs, const discard_comments& rhs); - friend bool operator<=(const discard_comments& lhs, const discard_comments& rhs); - friend bool operator> (const discard_comments& lhs, const discard_comments& rhs); - friend bool operator>=(const discard_comments& lhs, const discard_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); + friend bool operator>=(const preserve_comments& lhs, const preserve_comments& rhs); private: container_type comments; }; -inline bool operator==(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments == rhs.comments;} -inline bool operator!=(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments != rhs.comments;} -inline bool operator< (const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments < rhs.comments;} -inline bool operator<=(const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments <= rhs.comments;} -inline bool operator> (const discard_comments& lhs, const discard_comments& rhs) {return lhs.comments > rhs.comments;} -inline bool operator>=(const discard_comments& lhs, const discard_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 bool operator>=(const preserve_comments& lhs, const preserve_comments& rhs) {return lhs.comments >= rhs.comments;} -inline void swap(discard_comments& lhs, discard_comments& rhs) +inline void swap(preserve_comments& lhs, preserve_comments& rhs) { lhs.swap(rhs); return; @@ -263,7 +261,7 @@ struct discard_comments using reference = std::string&; using const_reference = std::string const&; using pointer = std::string*; - using const_pointer = std::string const&; + using const_pointer = std::string const*; using iterator = detail::empty_iterator; using const_iterator = detail::empty_iterator; using reverse_iterator = detail::empty_iterator; @@ -298,7 +296,7 @@ struct discard_comments iterator insert(const_iterator, std::initializer_list) {return iterator{};} template - iterator emplace(const_iterator, Ts&&) {return iterator{};} + iterator emplace(const_iterator, Ts&& ...) {return iterator{};} iterator erase(const_iterator) {return iterator{};} iterator erase(const_iterator, const_iterator) {return iterator{};} @@ -308,8 +306,6 @@ struct discard_comments void push_back(std::string&& ) {return;} void pop_back() {return;} - template - void emplace_back(Ts&& ...) {return;} template void emplace_back(Ts&& ...) {return;} @@ -360,7 +356,7 @@ inline bool operator==(const discard_comments&, const discard_comments&) noexcep 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 false;} inline bool operator>=(const discard_comments&, const discard_comments&) noexcept {return true;} inline void swap(const discard_comments&, const discard_comments&) noexcept {return;} From d30700517d50e2289ec6793136efadaf8a5f723c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 19:43:35 +0900 Subject: [PATCH 008/162] fix: add missing include file --- toml/region.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/toml/region.hpp b/toml/region.hpp index 2fb1eaa..923da9b 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace toml { From 351320491de6a552b12e6304691c78ebceda62a3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 19:46:20 +0900 Subject: [PATCH 009/162] fix: fix has_from_toml using basic_value --- toml/traits.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index 98f524b..a565d86 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -13,10 +13,14 @@ #endif // has_include() #endif // cplusplus >= C++17 +#include "comments.hpp" +#include +#include + namespace toml { - -class value; // forward decl +template class T, template class A> +class basic_value; namespace detail { @@ -58,7 +62,10 @@ struct has_from_toml_method_impl { template static std::true_type check( - decltype(std::declval().from_toml(std::declval<::toml::value>()))*); + decltype(std::declval().from_toml(std::declval<::toml::basic_value< + ::toml::discard_comments, std::unordered_map, std::vector>>() + ) + )*); template static std::false_type check(...); }; From 65540fbb5cb76bfce4824f76cec3312ba03e85a5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 19:47:10 +0900 Subject: [PATCH 010/162] fix: typos --- toml/types.hpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index 2c0d9d8..31e7717 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -6,13 +6,15 @@ #include "string.hpp" #include "traits.hpp" #include "comments.hpp" +#include +#include namespace toml { template Table, // map-like class - template Array> // vector-like class + template class Table, // map-like class + template class Array> // vector-like class class basic_value; using character = char; @@ -30,7 +32,7 @@ using floating = double; // "float" is a keyward, cannot use it here. // - local_time // default toml::value and default array/table -using value = basic_value; +using value = basic_value; enum class value_t : std::uint8_t { @@ -102,7 +104,7 @@ template struct enum_to_type{us // meta-function that converts from an exact toml type to the enum that corresponds to. template -struct type_to_enum : typename std::conditional< +struct type_to_enum : std::conditional< std::is_same::value, // if T == array_type, value_t_constant, // then value_t::array typename std::conditional< // else... @@ -110,7 +112,7 @@ struct type_to_enum : typename std::conditional< value_t_constant, // then value_t::table value_t_constant // else value_t::empty >::type - >::type {} + >::type {}; template struct type_to_enum: value_t_constant {}; template struct type_to_enum: value_t_constant {}; template struct type_to_enum: value_t_constant {}; @@ -152,15 +154,15 @@ struct is_convertible_to_toml_value : disjunction< std::is_same, // T is local_time or std::is_same, // T is local_datetime or std::is_same, // T is offset_datetime or - std::is_same // T is time_point or + std::is_same, // T is time_point or is_chrono_duration, // T is a duration or std::is_same, // T is an array type or - std::is_same, // T is an array type or - >{} + std::is_same // T is an array type or + >{}; // meta-function that returns value_t that represent the convertible type template -struct convertible_toml_type_of : typename std::conditional< +struct convertible_toml_type_of : std::conditional< /* if */ is_exact_toml_type::value, /* then */ value_t_constant::value>, /* else */ typename std::conditional< @@ -173,24 +175,23 @@ struct convertible_toml_type_of : typename std::conditional< /* then */ value_t_constant, /* else */ typename std::conditional< // ---------------------------------------------------------------------- - /* if */ std::is_same::value, + /* if */ std::is_same::value, /* then */ value_t_constant, /* else */ typename std::conditional< // ---------------------------------------------------------------------- - /* if */ is_string_literal, + /* if */ is_string_literal::value, /* then */ value_t_constant, /* else */ typename std::conditional< // ---------------------------------------------------------------------- - /* if */ is_chrono_duration, + /* if */ is_chrono_duration::value, /* then */ value_t_constant, /* else */ typename std::conditional< // ---------------------------------------------------------------------- - /* if */ std::is_same, + /* if */ std::is_same::value, /* then */ value_t_constant, - /* else */ value_t_constant, + /* else */ value_t_constant // ---------------------------------------------------------------------- - >::type>::type>::type>::type>::type>::type>::type - >{} + >::type>::type>::type>::type>::type>::type>::type {}; } // detail } // toml From 696e5bb66f6adbcc10fa6d22d857883882a80c65 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 20:16:59 +0900 Subject: [PATCH 011/162] feat: extend has_from_toml_method to be generic --- toml/traits.hpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index a565d86..7711900 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -60,13 +60,14 @@ struct has_resize_method_impl struct has_from_toml_method_impl { - template + template class Tb, template class A> static std::true_type check( - decltype(std::declval().from_toml(std::declval<::toml::basic_value< - ::toml::discard_comments, std::unordered_map, std::vector>>() - ) - )*); - template + decltype(std::declval().from_toml( + std::declval<::toml::basic_value>()))*); + + template class Tb, template class A> static std::false_type check(...); }; struct has_into_toml_method_impl @@ -94,9 +95,11 @@ struct has_mapped_type : decltype(has_mapped_type_impl::check(nullptr)){}; template struct has_resize_method : decltype(has_resize_method_impl::check(nullptr)){}; -template +template class Tb, template class A> struct has_from_toml_method -: decltype(has_from_toml_method_impl::check(nullptr)){}; +: decltype(has_from_toml_method_impl::check(nullptr)){}; + template struct has_into_toml_method : decltype(has_into_toml_method_impl::check(nullptr)){}; From 5c3c1bd0e7939f2d9ec3fec01e55d92ccbbf5a7b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 20:18:15 +0900 Subject: [PATCH 012/162] feat: add missing default array/table type --- toml/types.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/toml/types.hpp b/toml/types.hpp index 31e7717..e752507 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -33,6 +33,9 @@ using floating = double; // "float" is a keyward, cannot use it here. // default toml::value and default array/table using value = basic_value; +// TODO: consider to move these after including `value.hpp` +using array = std::vector; // typename value::array_type; +using table = std::unordered_map; // typename value::table_type; enum class value_t : std::uint8_t { From 5c5d8b686a28a9024102bea8cdd66a983680688d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 20:18:57 +0900 Subject: [PATCH 013/162] feat: introduce basic_value it is capable to change comment policy, backend container of an array and a table. --- toml/value.hpp | 1082 +++++++++++++++++++++++++++--------------------- 1 file changed, 608 insertions(+), 474 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index e42e6f5..6687ccd 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -4,44 +4,245 @@ #define TOML11_VALUE_HPP #include "traits.hpp" #include "into.hpp" +#include "from.hpp" #include "utility.hpp" #include "exception.hpp" #include "storage.hpp" #include "region.hpp" #include "types.hpp" -#include -#include -#include +#include "source_location.hpp" #include -#include -#if __cplusplus >= 201703L -#include -#endif namespace toml { namespace detail { + // to show error messages. not recommended for users. -region_base const& get_region(const value&); -template -void change_region(value&, Region&&); +template class T, template class A> +region_base const& get_region(const basic_value&); +template class T, template class A> +void change_region(basic_value&, Region&&); + +template class T, template class A> +[[noreturn]] inline void +throw_bad_cast(value_t actual, const ::toml::basic_value& v) +{ + throw type_error(detail::format_underline(concat_to_string( + "[error] toml::value bad_cast to ", Expected), { + {std::addressof(get_region(v)), + concat_to_string("the actual type is ", actual)} + })); +} + +// switch by `value_t` and call the corresponding `value::as_xxx()`. +template +struct switch_cast {}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::boolean& invoke(basic_value& v) noexcept + { + return v.as_boolean(); + } + template class T, template class A> + static ::toml::boolean const& invoke(basic_value const& v) noexcept + { + return v.as_boolean(); + } + template class T, template class A> + static ::toml::boolean&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_boolean(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::integer& invoke(basic_value& v) noexcept + { + return v.as_integer(); + } + template class T, template class A> + static ::toml::integer const& invoke(basic_value const& v) noexcept + { + return v.as_integer(); + } + template class T, template class A> + static ::toml::integer&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_integer(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::floating& invoke(basic_value& v) noexcept + { + return v.as_floating(); + } + template class T, template class A> + static ::toml::floating const& invoke(basic_value const& v) noexcept + { + return v.as_floating(); + } + template class T, template class A> + static ::toml::floating&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_floating(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::string& invoke(basic_value& v) noexcept + { + return v.as_string(); + } + template class T, template class A> + static ::toml::string const& invoke(basic_value const& v) noexcept + { + return v.as_string(); + } + template class T, template class A> + static ::toml::string&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_string(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::offset_datetime& invoke(basic_value& v) noexcept + { + return v.as_offset_datetime(); + } + template class T, template class A> + static ::toml::offset_datetime const& invoke(basic_value const& v) noexcept + { + return v.as_offset_datetime(); + } + template class T, template class A> + static ::toml::offset_datetime&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_offset_datetime(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_datetime& invoke(basic_value& v) noexcept + { + return v.as_local_datetime(); + } + template class T, template class A> + static ::toml::local_datetime const& invoke(basic_value const& v) noexcept + { + return v.as_local_datetime(); + } + template class T, template class A> + static ::toml::local_datetime&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_datetime(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_date& invoke(basic_value& v) noexcept + { + return v.as_local_date(); + } + template class T, template class A> + static ::toml::local_date const& invoke(basic_value const& v) noexcept + { + return v.as_local_date(); + } + template class T, template class A> + static ::toml::local_date&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_date(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static ::toml::local_time& invoke(basic_value& v) noexcept + { + return v.as_local_time(); + } + template class T, template class A> + static ::toml::local_time const& invoke(basic_value const& v) noexcept + { + return v.as_local_time(); + } + template class T, template class A> + static ::toml::local_time&& invoke(basic_value&& v) noexcept + { + return std::move(v).as_local_time(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static typename basic_value::array_type& + invoke(basic_value& v) noexcept + { + return v.as_array(); + } + template class T, template class A> + static typename basic_value::array_type const& + invoke(basic_value const& v) noexcept + { + return v.as_array(); + } + template class T, template class A> + static typename basic_value::array_type && + invoke(basic_value&& v) noexcept + { + return std::move(v).as_array(); + } +}; +template<> +struct switch_cast +{ + template class T, template class A> + static typename basic_value::table_type& + invoke(basic_value& v) noexcept + { + return v.as_table(); + } + template class T, template class A> + static typename basic_value::table_type const& + invoke(basic_value const& v) noexcept + { + return v.as_table(); + } + template class T, template class A> + static typename basic_value::table_type && + invoke(basic_value&& v) noexcept + { + return std::move(v).as_table(); + } +}; }// detail -template -struct value_traits -{ - constexpr static value_t type_index = detail::check_type(); - constexpr static bool is_toml_type = detail::is_valid(detail::check_type()); - typedef typename detail::toml_default_type::type type; -}; -template -constexpr value_t value_traits::type_index; -template -constexpr bool value_traits::is_toml_type; - -class value +template class Table, // map-like class + template class Array> // vector-like class +class basic_value { template static void assigner(T& dst, U&& v) @@ -55,85 +256,102 @@ class value public: - value() noexcept - : type_(value_t::Empty), + using comment_type = Comment; + using key_type = ::toml::key; + using value_type = basic_value; + using boolean_type = ::toml::boolean; + using integer_type = ::toml::integer; + using floating_type = ::toml::floating; + using string_type = ::toml::string; + using local_time = ::toml::local_time; + using local_date = ::toml::local_date; + using local_datetime = ::toml::local_datetime; + using offset_datetime = ::toml::offset_datetime; + using array_type = Array; + using table_type = Table; + + public: + + basic_value() noexcept + : type_(value_t::empty), region_info_(std::make_shared(region_base{})) {} + ~basic_value() noexcept {this->cleanup();} - ~value() noexcept {this->cleanup();} - - value(const value& v): type_(v.type()), region_info_(v.region_info_) + basic_value(const basic_value& v) + : type_(v.type()), region_info_(v.region_info_) { switch(v.type()) { - case value_t::Boolean : assigner(boolean_ , v.boolean_ ); break; - case value_t::Integer : assigner(integer_ , v.integer_ ); break; - case value_t::Float : assigner(floating_ , v.floating_ ); break; - case value_t::String : assigner(string_ , v.string_ ); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, v.offset_datetime_); break; - case value_t::LocalDatetime : assigner(local_datetime_ , v.local_datetime_ ); break; - case value_t::LocalDate : assigner(local_date_ , v.local_date_ ); break; - case value_t::LocalTime : assigner(local_time_ , v.local_time_ ); break; - case value_t::Array : assigner(array_ , v.array_ ); break; - case value_t::Table : assigner(table_ , v.table_ ); break; + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; default: break; } } - value(value&& v): type_(v.type()), region_info_(std::move(v.region_info_)) + basic_value(basic_value&& v) + : type_(v.type()), region_info_(std::move(v.region_info_)) { - switch(this->type_) + switch(this->type_) // here this->type_ is already initialized { - case value_t::Boolean : assigner(boolean_ , std::move(v.boolean_ )); break; - case value_t::Integer : assigner(integer_ , std::move(v.integer_ )); break; - case value_t::Float : assigner(floating_ , std::move(v.floating_ )); break; - case value_t::String : assigner(string_ , std::move(v.string_ )); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; - case value_t::LocalDatetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; - case value_t::LocalDate : assigner(local_date_ , std::move(v.local_date_ )); break; - case value_t::LocalTime : assigner(local_time_ , std::move(v.local_time_ )); break; - case value_t::Array : assigner(array_ , std::move(v.array_ )); break; - case value_t::Table : assigner(table_ , std::move(v.table_ )); break; + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; default: break; } } - value& operator=(const value& v) + basic_value& operator=(const basic_value& v) { this->cleanup(); this->region_info_ = v.region_info_; this->type_ = v.type(); switch(this->type_) { - case value_t::Boolean : assigner(boolean_ , v.boolean_ ); break; - case value_t::Integer : assigner(integer_ , v.integer_ ); break; - case value_t::Float : assigner(floating_ , v.floating_ ); break; - case value_t::String : assigner(string_ , v.string_ ); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, v.offset_datetime_); break; - case value_t::LocalDatetime : assigner(local_datetime_ , v.local_datetime_ ); break; - case value_t::LocalDate : assigner(local_date_ , v.local_date_ ); break; - case value_t::LocalTime : assigner(local_time_ , v.local_time_ ); break; - case value_t::Array : assigner(array_ , v.array_ ); break; - case value_t::Table : assigner(table_ , v.table_ ); break; + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; default: break; } return *this; } - value& operator=(value&& v) + basic_value& operator=(basic_value&& v) { this->cleanup(); this->region_info_ = std::move(v.region_info_); this->type_ = v.type(); switch(this->type_) { - case value_t::Boolean : assigner(boolean_ , std::move(v.boolean_ )); break; - case value_t::Integer : assigner(integer_ , std::move(v.integer_ )); break; - case value_t::Float : assigner(floating_ , std::move(v.floating_ )); break; - case value_t::String : assigner(string_ , std::move(v.string_ )); break; - case value_t::OffsetDatetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; - case value_t::LocalDatetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; - case value_t::LocalDate : assigner(local_date_ , std::move(v.local_date_ )); break; - case value_t::LocalTime : assigner(local_time_ , std::move(v.local_time_ )); break; - case value_t::Array : assigner(array_ , std::move(v.array_ )); break; - case value_t::Table : assigner(table_ , std::move(v.table_ )); break; + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; default: break; } return *this; @@ -141,25 +359,25 @@ class value // boolean ============================================================== - value(boolean b) - : type_(value_t::Boolean), + basic_value(boolean b) + : type_(value_t::boolean), region_info_(std::make_shared(region_base{})) { assigner(this->boolean_, b); } - value& operator=(boolean b) + basic_value& operator=(boolean b) { this->cleanup(); - this->type_ = value_t::Boolean; + this->type_ = value_t::boolean; this->region_info_ = std::make_shared(region_base{}); assigner(this->boolean_, b); return *this; } template - value(boolean b, detail::region reg) - : type_(value_t::Boolean), + basic_value(boolean b, detail::region reg) + : type_(value_t::boolean), region_info_(std::make_shared>(std::move(reg))) { assigner(this->boolean_, b); @@ -170,19 +388,20 @@ class value template, detail::negation>>::value, std::nullptr_t>::type = nullptr> - value(T i) - : type_(value_t::Integer), + basic_value(T i) + : type_(value_t::integer), region_info_(std::make_shared(region_base{})) { assigner(this->integer_, static_cast(i)); } template, - detail::negation> + detail::conjunction< + std::is_integral, + detail::negation> >::value, std::nullptr_t>::type = nullptr> - value(T i, detail::region reg) - : type_(value_t::Integer), + basic_value(T i, detail::region reg) + : type_(value_t::integer), region_info_(std::make_shared>(std::move(reg))) { assigner(this->integer_, static_cast(i)); @@ -191,10 +410,10 @@ class value template, detail::negation>>::value, std::nullptr_t>::type = nullptr> - value& operator=(T i) + basic_value& operator=(T i) { this->cleanup(); - this->type_ = value_t::Integer; + this->type_ = value_t::integer; this->region_info_ = std::make_shared(region_base{}); assigner(this->integer_, static_cast(i)); return *this; @@ -204,8 +423,8 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T f) - : type_(value_t::Float), + basic_value(T f) + : type_(value_t::floating), region_info_(std::make_shared(region_base{})) { assigner(this->floating_, f); @@ -213,8 +432,8 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T f, detail::region reg) - : type_(value_t::Float), + basic_value(T f, detail::region reg) + : type_(value_t::floating), region_info_(std::make_shared>(std::move(reg))) { assigner(this->floating_, f); @@ -222,10 +441,10 @@ class value template::value, std::nullptr_t>::type = nullptr> - value& operator=(T f) + basic_value& operator=(T f) { this->cleanup(); - this->type_ = value_t::Float; + this->type_ = value_t::floating; this->region_info_ = std::make_shared(region_base{}); assigner(this->floating_, f); return *this; @@ -233,87 +452,87 @@ class value // string =============================================================== - value(toml::string s) - : type_(value_t::String), + basic_value(toml::string s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, std::move(s)); } template - value(toml::string s, detail::region reg) - : type_(value_t::String), + basic_value(toml::string s, detail::region reg) + : type_(value_t::string), region_info_(std::make_shared>(std::move(reg))) { assigner(this->string_, std::move(s)); } - value& operator=(toml::string s) + basic_value& operator=(toml::string s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, s); return *this; } - value(std::string s) - : type_(value_t::String), + basic_value(std::string s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::move(s))); } - value& operator=(std::string s) + basic_value& operator=(std::string s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(std::move(s))); return *this; } - value(std::string s, string_t kind) - : type_(value_t::String), + basic_value(std::string s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::move(s), kind)); } - value(const char* s) - : type_(value_t::String), + basic_value(const char* s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::string(s))); } - value& operator=(const char* s) + basic_value& operator=(const char* s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(std::string(s))); return *this; } - value(const char* s, string_t kind) - : type_(value_t::String), + basic_value(const char* s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(std::string(s), kind)); } #if __cplusplus >= 201703L - value(std::string_view s) - : type_(value_t::String), + basic_value(std::string_view s) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(s)); } - value& operator=(std::string_view s) + basic_value& operator=(std::string_view s) { this->cleanup(); - this->type_ = value_t::String; + this->type_ = value_t::string ; this->region_info_ = std::make_shared(region_base{}); assigner(this->string_, toml::string(s)); return *this; } - value(std::string_view s, string_t kind) - : type_(value_t::String), + basic_value(std::string_view s, string_t kind) + : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(s, kind)); @@ -322,23 +541,23 @@ class value // local date =========================================================== - value(const local_date& ld) - : type_(value_t::LocalDate), + basic_value(const local_date& ld) + : type_(value_t::local_date), region_info_(std::make_shared(region_base{})) { assigner(this->local_date_, ld); } template - value(const local_date& ld, detail::region reg) - : type_(value_t::LocalDate), + basic_value(const local_date& ld, detail::region reg) + : type_(value_t::local_date), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_date_, ld); } - value& operator=(const local_date& ld) + basic_value& operator=(const local_date& ld) { this->cleanup(); - this->type_ = value_t::LocalDate; + this->type_ = value_t::local_date; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_date_, ld); return *this; @@ -346,39 +565,39 @@ class value // local time =========================================================== - value(const local_time& lt) - : type_(value_t::LocalTime), + basic_value(const local_time& lt) + : type_(value_t::local_time), region_info_(std::make_shared(region_base{})) { assigner(this->local_time_, lt); } template - value(const local_time& lt, detail::region reg) - : type_(value_t::LocalTime), + basic_value(const local_time& lt, detail::region reg) + : type_(value_t::local_time), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_time_, lt); } - value& operator=(const local_time& lt) + basic_value& operator=(const local_time& lt) { this->cleanup(); - this->type_ = value_t::LocalTime; + this->type_ = value_t::local_time; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_time_, lt); return *this; } template - value(const std::chrono::duration& dur) - : type_(value_t::LocalTime), + basic_value(const std::chrono::duration& dur) + : type_(value_t::local_time), region_info_(std::make_shared(region_base{})) { assigner(this->local_time_, local_time(dur)); } template - value& operator=(const std::chrono::duration& dur) + basic_value& operator=(const std::chrono::duration& dur) { this->cleanup(); - this->type_ = value_t::LocalTime; + this->type_ = value_t::local_time; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_time_, local_time(dur)); return *this; @@ -386,23 +605,23 @@ class value // local datetime ======================================================= - value(const local_datetime& ldt) - : type_(value_t::LocalDatetime), + basic_value(const local_datetime& ldt) + : type_(value_t::local_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->local_datetime_, ldt); } template - value(const local_datetime& ldt, detail::region reg) - : type_(value_t::LocalDatetime), + basic_value(const local_datetime& ldt, detail::region reg) + : type_(value_t::local_datetime), region_info_(std::make_shared>(std::move(reg))) { assigner(this->local_datetime_, ldt); } - value& operator=(const local_datetime& ldt) + basic_value& operator=(const local_datetime& ldt) { this->cleanup(); - this->type_ = value_t::LocalDatetime; + this->type_ = value_t::local_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->local_datetime_, ldt); return *this; @@ -410,37 +629,37 @@ class value // offset datetime ====================================================== - value(const offset_datetime& odt) - : type_(value_t::OffsetDatetime), + basic_value(const offset_datetime& odt) + : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->offset_datetime_, odt); } template - value(const offset_datetime& odt, detail::region reg) - : type_(value_t::OffsetDatetime), + basic_value(const offset_datetime& odt, detail::region reg) + : type_(value_t::offset_datetime), region_info_(std::make_shared>(std::move(reg))) { assigner(this->offset_datetime_, odt); } - value& operator=(const offset_datetime& odt) + basic_value& operator=(const offset_datetime& odt) { this->cleanup(); - this->type_ = value_t::OffsetDatetime; + this->type_ = value_t::offset_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->offset_datetime_, odt); return *this; } - value(const std::chrono::system_clock::time_point& tp) - : type_(value_t::OffsetDatetime), + basic_value(const std::chrono::system_clock::time_point& tp) + : type_(value_t::offset_datetime), region_info_(std::make_shared(region_base{})) { assigner(this->offset_datetime_, offset_datetime(tp)); } - value& operator=(const std::chrono::system_clock::time_point& tp) + basic_value& operator=(const std::chrono::system_clock::time_point& tp) { this->cleanup(); - this->type_ = value_t::OffsetDatetime; + this->type_ = value_t::offset_datetime; this->region_info_ = std::make_shared(region_base{}); assigner(this->offset_datetime_, offset_datetime(tp)); return *this; @@ -448,47 +667,49 @@ class value // array ================================================================ - value(const array& ary) - : type_(value_t::Array), + basic_value(const array_type& ary) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { assigner(this->array_, ary); } template - value(const array& ary, detail::region reg) - : type_(value_t::Array), + basic_value(const array_type& ary, detail::region reg) + : type_(value_t::array), region_info_(std::make_shared>(std::move(reg))) { assigner(this->array_, ary); } - value& operator=(const array& ary) + basic_value& operator=(const array_type& ary) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); assigner(this->array_, ary); return *this; } - template::is_toml_type, + template::value, std::nullptr_t>::type = nullptr> - value(std::initializer_list list) - : type_(value_t::Array), + basic_value(std::initializer_list list) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(auto& elem : list) {ary.emplace_back(std::move(elem));} assigner(this->array_, std::move(ary)); } - template::is_toml_type, + template::value, std::nullptr_t>::type = nullptr> - value& operator=(std::initializer_list list) + basic_value& operator=(std::initializer_list list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(auto& elem : list) {ary.emplace_back(std::move(elem));} assigner(this->array_, std::move(ary)); return *this; @@ -496,23 +717,23 @@ class value template::value, std::nullptr_t>::type = nullptr> - value(T&& list) - : type_(value_t::Array), + basic_value(T&& list) + : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(const auto& elem : list) {ary.emplace_back(elem);} assigner(this->array_, std::move(ary)); } template::value, std::nullptr_t>::type = nullptr> - value& operator=(T&& list) + basic_value& operator=(T&& list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - array ary; ary.reserve(list.size()); + array_type ary; ary.reserve(list.size()); for(const auto& elem : list) {ary.emplace_back(elem);} assigner(this->array_, std::move(ary)); return *this; @@ -520,42 +741,42 @@ class value // table ================================================================ - value(const table& tab) - : type_(value_t::Table), + basic_value(const table_type& tab) + : type_(value_t::table), region_info_(std::make_shared(region_base{})) { assigner(this->table_, tab); } template - value(const table& tab, detail::region reg) - : type_(value_t::Table), + basic_value(const table_type& tab, detail::region reg) + : type_(value_t::table), region_info_(std::make_shared>(std::move(reg))) { assigner(this->table_, tab); } - value& operator=(const table& tab) + basic_value& operator=(const table_type& tab) { this->cleanup(); - this->type_ = value_t::Table; + this->type_ = value_t::table ; this->region_info_ = std::make_shared(region_base{}); assigner(this->table_, tab); return *this; } - value(std::initializer_list> list) - : type_(value_t::Table), + basic_value(std::initializer_list> list) + : type_(value_t::table), region_info_(std::make_shared(region_base{})) { - table tab; + table_type tab; for(const auto& elem : list) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); } - value& operator=(std::initializer_list> list) + basic_value& operator=(std::initializer_list> list) { this->cleanup(); - this->type_ = value_t::Array; + this->type_ = value_t::array ; this->region_info_ = std::make_shared(region_base{}); - table tab; + table_type tab; for(const auto& elem : list) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); return *this; @@ -565,17 +786,13 @@ class value // convert using into_toml() method ------------------------------------- - template>, // not a toml::value - detail::has_into_toml_method // but has `into_toml` method - >::value, std::nullptr_t>::type = nullptr> - value(const T& ud): value(ud.into_toml()) {} + template::value, std::nullptr_t>::type = nullptr> + basic_value(const T& ud): basic_value(ud.into_toml()) {} - template>, // not a toml::value - detail::has_into_toml_method // but has `into_toml` method - >::value, std::nullptr_t>::type = nullptr> - value& operator=(const T& ud) + template::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const T& ud) { *this = ud.into_toml(); return *this; @@ -583,17 +800,11 @@ class value // convert using into struct ----------------------------------------- - template>::value, - std::nullptr_t>::type = nullptr, - std::size_t S = sizeof(::toml::into)> - value(const T& ud): value(::toml::into::into_toml(ud)) {} + template)> + basic_value(const T& ud): basic_value(::toml::into::into_toml(ud)) {} - template>::value, - std::nullptr_t>::type = nullptr, - std::size_t S = sizeof(::toml::into)> - value& operator=(const T& ud) + template)> + basic_value& operator=(const T& ud) { *this = ::toml::into::into_toml(ud); return *this; @@ -602,37 +813,64 @@ class value // for internal use ------------------------------------------------------ template::value, std::nullptr_t>::type = nullptr> - value(std::pair> parse_result) - : value(std::move(parse_result.first), std::move(parse_result.second)) + detail::is_exact_toml_type::value, + std::nullptr_t>::type = nullptr> + basic_value(std::pair> parse_result) + : basic_value(std::move(parse_result.first), std::move(parse_result.second)) {} // type checking and casting ============================================ - template - bool is() const noexcept {return value_traits::type_index == this->type_;} + template::value, + std::nullptr_t>::type = nullptr> + bool is() const noexcept + { + return detail::type_to_enum::value == this->type_; + } bool is(value_t t) const noexcept {return t == this->type_;} - bool is_uninitialized() const noexcept {return this->is(value_t::Empty );} - bool is_boolean() const noexcept {return this->is(value_t::Boolean );} - bool is_integer() const noexcept {return this->is(value_t::Integer );} - bool is_float() const noexcept {return this->is(value_t::Float );} - bool is_string() const noexcept {return this->is(value_t::String );} - bool is_offset_datetime() const noexcept {return this->is(value_t::OffsetDatetime);} - bool is_local_datetime() const noexcept {return this->is(value_t::LocalDatetime );} - bool is_local_date() const noexcept {return this->is(value_t::LocalDate );} - bool is_local_time() const noexcept {return this->is(value_t::LocalTime );} - bool is_array() const noexcept {return this->is(value_t::Array );} - bool is_table() const noexcept {return this->is(value_t::Table );} + bool is_uninitialized() const noexcept {return this->is(value_t::empty );} + bool is_boolean() const noexcept {return this->is(value_t::boolean );} + bool is_integer() const noexcept {return this->is(value_t::integer );} + bool is_float() const noexcept {return this->is(value_t::floating );} + bool is_string() const noexcept {return this->is(value_t::string );} + bool is_offset_datetime() const noexcept {return this->is(value_t::offset_datetime);} + bool is_local_datetime() const noexcept {return this->is(value_t::local_datetime );} + bool is_local_date() const noexcept {return this->is(value_t::local_date );} + bool is_local_time() const noexcept {return this->is(value_t::local_time );} + bool is_array() const noexcept {return this->is(value_t::array );} + bool is_table() const noexcept {return this->is(value_t::table );} value_t type() const {return type_;} template - typename detail::toml_default_type::type& cast() &; + typename detail::enum_to_type::type& cast() & + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } template - typename detail::toml_default_type::type const& cast() const&; + typename detail::enum_to_type::type const& cast() const& + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(*this); + } template - typename detail::toml_default_type::type&& cast() &&; + typename detail::enum_to_type::type&& cast() && + { + if(this->type_ != T) + { + detail::throw_bad_cast(this->type_, *this); + } + return detail::switch_cast::invoke(std::move(*this)); + } boolean const& as_boolean() const& noexcept {return this->boolean_;} integer const& as_integer() const& noexcept {return this->integer_;} @@ -642,8 +880,8 @@ class value local_datetime const& as_local_datetime() const& noexcept {return this->local_datetime_;} local_date const& as_local_date() const& noexcept {return this->local_date_;} local_time const& as_local_time() const& noexcept {return this->local_time_;} - array const& as_array() const& noexcept {return this->array_.value();} - table const& as_table() const& noexcept {return this->table_.value();} + array_type const& as_array() const& noexcept {return this->array_.value();} + table_type const& as_table() const& noexcept {return this->table_.value();} boolean & as_boolean() & noexcept {return this->boolean_;} integer & as_integer() & noexcept {return this->integer_;} @@ -653,8 +891,8 @@ class value local_datetime & as_local_datetime() & noexcept {return this->local_datetime_;} local_date & as_local_date() & noexcept {return this->local_date_;} local_time & as_local_time() & noexcept {return this->local_time_;} - array & as_array() & noexcept {return this->array_.value();} - table & as_table() & noexcept {return this->table_.value();} + array_type & as_array() & noexcept {return this->array_.value();} + table_type & as_table() & noexcept {return this->table_.value();} boolean && as_boolean() && noexcept {return std::move(this->boolean_);} integer && as_integer() && noexcept {return std::move(this->integer_);} @@ -664,20 +902,17 @@ class value local_datetime && as_local_datetime() && noexcept {return std::move(this->local_datetime_);} local_date && as_local_date() && noexcept {return std::move(this->local_date_);} local_time && as_local_time() && noexcept {return std::move(this->local_time_);} - array && as_array() && noexcept {return std::move(this->array_.value());} - table && as_table() && noexcept {return std::move(this->table_.value());} + array_type && as_array() && noexcept {return std::move(this->array_.value());} + table_type && as_table() && noexcept {return std::move(this->table_.value());} - std::string comment() const + comment_type const& comments() const noexcept { - return this->region_info_->comment(); + return this->comments_; } - std::string comment_before() const + + source_location location() const { - return this->region_info_->comment_before(); - } - std::string comment_inline() const - { - return this->region_info_->comment_inline(); + return source_location(this->region_info_); } private: @@ -686,29 +921,30 @@ class value { switch(this->type_) { - case value_t::String : {string_.~string(); return;} - case value_t::Array : {array_.~array_storage(); return;} - case value_t::Table : {table_.~table_storage(); return;} + case value_t::string : {string_.~string(); return;} + case value_t::array : {array_.~array_storage(); return;} + case value_t::table : {table_.~table_storage(); return;} default : return; } } // for error messages - friend region_base const& detail::get_region(const value&); + template class T, template class A> + friend region_base const& detail::get_region(const basic_value&); - template - friend void detail::change_region(value&, Region&&); + template class T, template class A> + friend void detail::change_region(basic_value&, Region&&); private: - using array_storage = detail::storage; - using table_storage = detail::storage
; + using array_storage = detail::storage; + using table_storage = detail::storage; - value_t type_; - - // for error message information. + comment_type comments_; std::shared_ptr region_info_; - + value_t type_; union { boolean boolean_; @@ -726,13 +962,16 @@ class value namespace detail { -inline region_base const& get_region(const value& v) +template class T, template class A> +inline region_base const& get_region(const basic_value& v) { return *(v.region_info_); } -template -void change_region(value& v, Region&& reg) +template class T, template class A> +void change_region(basic_value& v, Region&& reg) { using region_type = typename std::remove_reference< typename std::remove_cv::type @@ -743,343 +982,238 @@ void change_region(value& v, Region&& reg) v.region_info_ = new_reg; return; } - -template -[[noreturn]] inline void throw_bad_cast(value_t actual, const ::toml::value& v) -{ - throw type_error(detail::format_underline(concat_to_string( - "[error] toml::value bad_cast to ", Expected), { - {std::addressof(get_region(v)), - concat_to_string("the actual type is ", actual)} - })); -} - -template -struct switch_cast; -template<> -struct switch_cast -{ - static ::toml::boolean& invoke(value& v) {return v.as_boolean();} - static ::toml::boolean const& invoke(value const& v) {return v.as_boolean();} - static ::toml::boolean&& invoke(value&& v) {return std::move(v).as_boolean();} -}; -template<> -struct switch_cast -{ - static ::toml::integer& invoke(value& v) {return v.as_integer();} - static ::toml::integer const& invoke(value const& v) {return v.as_integer();} - static ::toml::integer&& invoke(value&& v) {return std::move(v).as_integer();} -}; -template<> -struct switch_cast -{ - static ::toml::floating& invoke(value& v) {return v.as_float();} - static ::toml::floating const& invoke(value const& v) {return v.as_float();} - static ::toml::floating&& invoke(value&& v) {return std::move(v).as_float();} -}; -template<> -struct switch_cast -{ - static ::toml::string& invoke(value& v) {return v.as_string();} - static ::toml::string const& invoke(value const& v) {return v.as_string();} - static ::toml::string&& invoke(value&& v) {return std::move(v).as_string();} -}; -template<> -struct switch_cast -{ - static ::toml::offset_datetime& invoke(value& v) {return v.as_offset_datetime();} - static ::toml::offset_datetime const& invoke(value const& v) {return v.as_offset_datetime();} - static ::toml::offset_datetime&& invoke(value&& v) {return std::move(v).as_offset_datetime();} -}; -template<> -struct switch_cast -{ - static ::toml::local_datetime& invoke(value& v) {return v.as_local_datetime();} - static ::toml::local_datetime const& invoke(value const& v) {return v.as_local_datetime();} - static ::toml::local_datetime&& invoke(value&& v) {return std::move(v).as_local_datetime();} -}; -template<> -struct switch_cast -{ - static ::toml::local_date& invoke(value& v) {return v.as_local_date();} - static ::toml::local_date const& invoke(value const& v) {return v.as_local_date();} - static ::toml::local_date&& invoke(value&& v) {return std::move(v).as_local_date();} -}; -template<> -struct switch_cast -{ - static ::toml::local_time& invoke(value& v) {return v.as_local_time();} - static ::toml::local_time const& invoke(value const& v) {return v.as_local_time();} - static ::toml::local_time&& invoke(value&& v) {return std::move(v).as_local_time();} -}; -template<> -struct switch_cast -{ - static ::toml::array& invoke(value& v) {return v.as_array();} - static ::toml::array const& invoke(value const& v) {return v.as_array();} - static ::toml::array&& invoke(value&& v) {return std::move(v).as_array();} -}; -template<> -struct switch_cast -{ - static ::toml::table& invoke(value& v) {return v.as_table();} - static ::toml::table const& invoke(value const& v) {return v.as_table();} - static ::toml::table&& invoke(value&& v) {return std::move(v).as_table();} -}; }// detail -template -typename detail::toml_default_type::type& value::cast() & -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(*this); -} -template -typename detail::toml_default_type::type const& value::cast() const& -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(*this); -} -template -typename detail::toml_default_type::type&& value::cast() && -{ - if(T != this->type_) - { - detail::throw_bad_cast(this->type_, *this); - } - return detail::switch_cast::invoke(std::move(*this)); -} - -inline bool operator==(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool +operator==(const basic_value& lhs, const basic_value& rhs) { if(lhs.type() != rhs.type()){return false;} switch(lhs.type()) { - case value_t::Boolean : + case value_t::boolean : { return lhs.as_boolean() == rhs.as_boolean(); } - case value_t::Integer : + case value_t::integer : { return lhs.as_integer() == rhs.as_integer(); } - case value_t::Float : + case value_t::floating : { return lhs.as_float() == rhs.as_float(); } - case value_t::String : + case value_t::string : { return lhs.as_string() == rhs.as_string(); } - case value_t::OffsetDatetime: + case value_t::offset_datetime: { return lhs.as_offset_datetime() == rhs.as_offset_datetime(); } - case value_t::LocalDatetime: + case value_t::local_datetime: { return lhs.as_local_datetime() == rhs.as_local_datetime(); } - case value_t::LocalDate: + case value_t::local_date: { return lhs.as_local_date() == rhs.as_local_date(); } - case value_t::LocalTime: + case value_t::local_time: { return lhs.as_local_time() == rhs.as_local_time(); } - case value_t::Array : + case value_t::array : { return lhs.as_array() == rhs.as_array(); } - case value_t::Table : + case value_t::table : { return lhs.as_table() == rhs.as_table(); } - case value_t::Empty : {return true; } - case value_t::Unknown : {return false;} - default: {return false;} + case value_t::empty : {return true; } + default: {return false;} } } -inline bool operator<(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool +operator<(const basic_value& lhs, const basic_value& rhs) { if(lhs.type() != rhs.type()){return (lhs.type() < rhs.type());} switch(lhs.type()) { - case value_t::Boolean : + case value_t::boolean : { return lhs.as_boolean() < rhs.as_boolean(); } - case value_t::Integer : + case value_t::integer : { return lhs.as_integer() < rhs.as_integer(); } - case value_t::Float : + case value_t::floating : { return lhs.as_float() < rhs.as_float(); } - case value_t::String : + case value_t::string : { return lhs.as_string() < rhs.as_string(); } - case value_t::OffsetDatetime: + case value_t::offset_datetime: { return lhs.as_offset_datetime() < rhs.as_offset_datetime(); } - case value_t::LocalDatetime: + case value_t::local_datetime: { return lhs.as_local_datetime() < rhs.as_local_datetime(); } - case value_t::LocalDate: + case value_t::local_date: { return lhs.as_local_date() < rhs.as_local_date(); } - case value_t::LocalTime: + case value_t::local_time: { return lhs.as_local_time() < rhs.as_local_time(); } - case value_t::Array : + case value_t::array : { return lhs.as_array() < rhs.as_array(); } - case value_t::Table : + case value_t::table : { return lhs.as_table() < rhs.as_table(); } - case value_t::Empty : {return false;} - case value_t::Unknown : {return false;} - default: {return false;} + case value_t::empty : {return false;} + default: {return false;} } } -inline bool operator!=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator!=(const basic_value& lhs, const basic_value& rhs) { return !(lhs == rhs); } -inline bool operator<=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator<=(const basic_value& lhs, const basic_value& rhs) { return (lhs < rhs) || (lhs == rhs); } -inline bool operator>(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator>(const basic_value& lhs, const basic_value& rhs) { return !(lhs <= rhs); } -inline bool operator>=(const toml::value& lhs, const toml::value& rhs) +template class T, template class A> +inline bool operator>=(const basic_value& lhs, const basic_value& rhs) { return !(lhs < rhs); } -inline std::string format_error(const std::string& err_msg, - const toml::value& v, const std::string& comment, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v)), comment} - }, std::move(hints)); -} +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v, const std::string& comment, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v)), comment} +// }, std::move(hints)); +// } +// +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v1, const std::string& comment1, +// const toml::basic_value& v2, const std::string& comment2, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v1)), comment1}, +// {std::addressof(detail::get_region(v2)), comment2} +// }, std::move(hints)); +// } +// +// inline std::string format_error(const std::string& err_msg, +// const toml::basic_value& v1, const std::string& comment1, +// const toml::basic_value& v2, const std::string& comment2, +// const toml::basic_value& v3, const std::string& comment3, +// std::vector hints = {}) +// { +// return detail::format_underline(err_msg, +// std::vector>{ +// {std::addressof(detail::get_region(v1)), comment1}, +// {std::addressof(detail::get_region(v2)), comment2}, +// {std::addressof(detail::get_region(v3)), comment3} +// }, std::move(hints)); +// } -inline std::string format_error(const std::string& err_msg, - const toml::value& v1, const std::string& comment1, - const toml::value& v2, const std::string& comment2, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v1)), comment1}, - {std::addressof(detail::get_region(v2)), comment2} - }, std::move(hints)); -} - -inline std::string format_error(const std::string& err_msg, - const toml::value& v1, const std::string& comment1, - const toml::value& v2, const std::string& comment2, - const toml::value& v3, const std::string& comment3, - std::vector hints = {}) -{ - return detail::format_underline(err_msg, - std::vector>{ - {std::addressof(detail::get_region(v1)), comment1}, - {std::addressof(detail::get_region(v2)), comment2}, - {std::addressof(detail::get_region(v3)), comment3} - }, std::move(hints)); -} - -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, const toml::value& v) +visit(Visitor&& visitor, const toml::basic_value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.as_boolean ());} - case value_t::Integer : {return visitor(v.as_integer ());} - case value_t::Float : {return visitor(v.as_float ());} - case value_t::String : {return visitor(v.as_string ());} - case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());} - case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());} - case value_t::LocalDate : {return visitor(v.as_local_date ());} - case value_t::LocalTime : {return visitor(v.as_local_time ());} - case value_t::Array : {return visitor(v.as_array ());} - case value_t::Table : {return visitor(v.as_table ());} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_float ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, toml::value& v) +visit(Visitor&& visitor, toml::basic_value& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(v.as_boolean ());} - case value_t::Integer : {return visitor(v.as_integer ());} - case value_t::Float : {return visitor(v.as_float ());} - case value_t::String : {return visitor(v.as_string ());} - case value_t::OffsetDatetime: {return visitor(v.as_offset_datetime());} - case value_t::LocalDatetime : {return visitor(v.as_local_datetime ());} - case value_t::LocalDate : {return visitor(v.as_local_date ());} - case value_t::LocalTime : {return visitor(v.as_local_time ());} - case value_t::Array : {return visitor(v.as_array ());} - case value_t::Table : {return visitor(v.as_table ());} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(v.as_boolean ());} + case value_t::integer : {return visitor(v.as_integer ());} + case value_t::floating : {return visitor(v.as_float ());} + case value_t::string : {return visitor(v.as_string ());} + case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} + case value_t::local_datetime : {return visitor(v.as_local_datetime ());} + case value_t::local_date : {return visitor(v.as_local_date ());} + case value_t::local_time : {return visitor(v.as_local_time ());} + case value_t::array : {return visitor(v.as_array ());} + case value_t::table : {return visitor(v.as_table ());} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } -template +template class T, template class A> detail::return_type_of_t -visit(Visitor&& visitor, toml::value&& v) +visit(Visitor&& visitor, toml::basic_value&& v) { switch(v.type()) { - case value_t::Boolean : {return visitor(std::move(v.as_boolean ()));} - case value_t::Integer : {return visitor(std::move(v.as_integer ()));} - case value_t::Float : {return visitor(std::move(v.as_float ()));} - case value_t::String : {return visitor(std::move(v.as_string ()));} - case value_t::OffsetDatetime: {return visitor(std::move(v.as_offset_datetime()));} - case value_t::LocalDatetime : {return visitor(std::move(v.as_local_datetime ()));} - case value_t::LocalDate : {return visitor(std::move(v.as_local_date ()));} - case value_t::LocalTime : {return visitor(std::move(v.as_local_time ()));} - case value_t::Array : {return visitor(std::move(v.as_array ()));} - case value_t::Table : {return visitor(std::move(v.as_table ()));} - case value_t::Empty : break; - case value_t::Unknown : break; + case value_t::boolean : {return visitor(std::move(v.as_boolean ()));} + case value_t::integer : {return visitor(std::move(v.as_integer ()));} + case value_t::floating : {return visitor(std::move(v.as_float ()));} + case value_t::string : {return visitor(std::move(v.as_string ()));} + case value_t::offset_datetime: {return visitor(std::move(v.as_offset_datetime()));} + case value_t::local_datetime : {return visitor(std::move(v.as_local_datetime ()));} + case value_t::local_date : {return visitor(std::move(v.as_local_date ()));} + case value_t::local_time : {return visitor(std::move(v.as_local_time ()));} + case value_t::array : {return visitor(std::move(v.as_array ()));} + case value_t::table : {return visitor(std::move(v.as_table ()));} + case value_t::empty : break; default: break; } - throw std::runtime_error(format_error("[error] toml::visit: toml::value " - "does not have any valid value.", v, "here")); + throw std::runtime_error(format_error("[error] toml::visit: toml::basic_value " + "does not have any valid basic_value.", v, "here")); } }// toml From f9b5166c093b06ce920d6fdf3d99002b5483381e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 1 Jun 2019 23:58:17 +0900 Subject: [PATCH 014/162] refactor: move default value types to value.hpp --- toml/types.hpp | 10 +++++----- toml/value.hpp | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index e752507..6e7fbaa 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -31,11 +31,11 @@ using floating = double; // "float" is a keyward, cannot use it here. // - local_date // - local_time -// default toml::value and default array/table -using value = basic_value; -// TODO: consider to move these after including `value.hpp` -using array = std::vector; // typename value::array_type; -using table = std::unordered_map; // typename value::table_type; +// default toml::value and default array/table. these are defined after defining +// basic_value itself. +// using value = basic_value; +// using array = typename value::array_type; +// using table = typename value::table_type; enum class value_t : std::uint8_t { diff --git a/toml/value.hpp b/toml/value.hpp index 6687ccd..8e7250f 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -960,6 +960,11 @@ class basic_value }; }; +// default toml::value and default array/table. +using value = basic_value; +using array = typename value::array_type; +using table = typename value::table_type; + namespace detail { template Date: Sun, 2 Jun 2019 00:02:31 +0900 Subject: [PATCH 015/162] feat: enable to convert preserve/discard comments --- toml/comments.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/toml/comments.hpp b/toml/comments.hpp index ef67de4..f43d02a 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -18,6 +18,7 @@ // error whenever you access to the element. namespace toml { +struct discard_comments; // forward decl // use it in the following way // @@ -54,6 +55,7 @@ struct preserve_comments explicit preserve_comments(std::vector&& c) : comments(std::move(c)) {} + 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) {} @@ -276,6 +278,7 @@ struct discard_comments explicit discard_comments(const std::vector&) noexcept {} explicit discard_comments(std::vector&&) noexcept {} + explicit discard_comments(const preserve_comments&) noexcept {} explicit discard_comments(size_type) noexcept {} discard_comments(size_type, const std::string&) noexcept {} From 44184026f91e2d4d8b1d04352d7645f7c5bfe417 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 00:13:12 +0900 Subject: [PATCH 016/162] feat: enable to convert different basic_values --- toml/value.hpp | 85 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 8e7250f..9e60ff6 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -38,7 +38,7 @@ throw_bad_cast(value_t actual, const ::toml::basic_value& v) })); } -// switch by `value_t` and call the corresponding `value::as_xxx()`. +// switch by `value_t` and call the corresponding `value::as_xxx()`. {{{ template struct switch_cast {}; template<> @@ -236,7 +236,8 @@ struct switch_cast { return std::move(v).as_table(); } -}; +}; // }}} + }// detail templatecleanup();} basic_value(const basic_value& v) - : type_(v.type()), region_info_(v.region_info_) + : type_(v.type()), region_info_(v.region_info_), comments_(v.comments_) { switch(v.type()) { @@ -297,7 +298,8 @@ class basic_value } } basic_value(basic_value&& v) - : type_(v.type()), region_info_(std::move(v.region_info_)) + : type_(v.type()), region_info_(std::move(v.region_info_)), + comments_(std::move(comments_)) { switch(this->type_) // here this->type_ is already initialized { @@ -318,6 +320,7 @@ class basic_value { this->cleanup(); this->region_info_ = v.region_info_; + this->comments_ = v.comments_; this->type_ = v.type(); switch(this->type_) { @@ -339,6 +342,7 @@ class basic_value { this->cleanup(); this->region_info_ = std::move(v.region_info_); + this->comments_ = std::move(v.comments_); this->type_ = v.type(); switch(this->type_) { @@ -357,6 +361,73 @@ class basic_value return *this; } + // ----------------------------------------------------------------------- + // conversion between different basic_values. + template class T, + template class A> + basic_value(const basic_value& v) + : type_(v.type()), region_info_(v.region_info_), comments_(v.comments_) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.array_.begin(), v.array_.end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.table_.begin(), v.table_.end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + } + template class T, + template class A> + basic_value& operator=(const basic_value& v) + { + this->region_info_ = v.region_info_; + this->comments_ = v.comments_; + this->type_ = v.type_; + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.array_.begin(), v.array_.end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.table_.begin(), v.table_.end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + } + // boolean ============================================================== basic_value(boolean b) @@ -942,9 +1013,7 @@ class basic_value using array_storage = detail::storage; using table_storage = detail::storage; - comment_type comments_; - std::shared_ptr region_info_; - value_t type_; + value_t type_; union { boolean boolean_; @@ -958,6 +1027,8 @@ class basic_value array_storage array_; table_storage table_; }; + std::shared_ptr region_info_; + comment_type comments_; }; // default toml::value and default array/table. From 5792411d5ef318e7806fec1bbab368831b619de6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 15:15:43 +0900 Subject: [PATCH 017/162] feat: add default template argument to basic_value --- toml/value.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 9e60ff6..4dfdd0a 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -241,8 +241,8 @@ struct switch_cast }// detail template class Table, // map-like class - template class Array> // vector-like class + template class Table = std::unordered_map, + template class Array = std::vector> class basic_value { template From 9676499ab530562da87cb5febd1f5a81a41490b9 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 15:29:34 +0900 Subject: [PATCH 018/162] refactor: move file inclusion to correct position --- toml/traits.hpp | 1 - toml/value.hpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index 7711900..55127a6 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -13,7 +13,6 @@ #endif // has_include() #endif // cplusplus >= C++17 -#include "comments.hpp" #include #include diff --git a/toml/value.hpp b/toml/value.hpp index 4dfdd0a..220915f 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -11,6 +11,7 @@ #include "region.hpp" #include "types.hpp" #include "source_location.hpp" +#include "comments.hpp" #include namespace toml From e1556183d19d812668977e62eac376b86cff73bc Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 17:12:01 +0900 Subject: [PATCH 019/162] refactor: remove unused include files --- toml/traits.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index 55127a6..a994d6d 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -13,9 +13,6 @@ #endif // has_include() #endif // cplusplus >= C++17 -#include -#include - namespace toml { template class T, template class A> From 725d915ba98414e9364d684b2163a90bf69c2df6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 17:31:49 +0900 Subject: [PATCH 020/162] feat(WIP): update toml::get --- toml/get.hpp | 155 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 62 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index cf2cec4..0f5ff92 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -10,50 +10,60 @@ namespace toml { +// C++14 alias +template +using enable_if_t = typename std::enable_if::type; + // ============================================================================ // exact toml::* type -template::value, std::nullptr_t>::type = nullptr> -inline T& get(value& v) +template class M, template class V> +enable_if_t>::value, T> & +get(basic_value& v) { - return v.cast::value>(); + return v.template cast>::value>(); } -template::value, std::nullptr_t>::type = nullptr> -inline T const& get(const value& v) +template class M, template class V> +enable_if_t>::value, T> const& +get(const basic_value& v) { - return v.cast::value>(); + return v.template cast>::value>(); } -template::value, std::nullptr_t>::type = nullptr> -inline T&& get(value&& v) +template class M, template class V> +enable_if_t>::value, T> && +get(basic_value&& v) { - return std::move(v.cast::value>()); + return v.template cast>::value>(); } // ============================================================================ // T == toml::value; identity transformation. -template::value, std::nullptr_t>::type = nullptr> -inline T& get(value& v) +template class M, template class V> +inline enable_if_t>::value, T>& +get(basic_value& v) { return v; } -template::value, std::nullptr_t>::type = nullptr> -inline T const& get(const value& v) +template class M, template class V> +inline enable_if_t>::value, T> const& +get(const basic_value& v) { return v; } -template::value, std::nullptr_t>::type = nullptr> -inline T&& get(value&& v) +template class M, template class V> +inline enable_if_t>::value, T> && +get(basic_value&& v) { return std::move(v); } @@ -61,104 +71,125 @@ inline T&& get(value&& v) // ============================================================================ // integer convertible from toml::Integer -template class M, template class V> +inline enable_if_t, // T is integral detail::negation>, // but not bool - detail::negation> // but not toml::integer - >::value, std::nullptr_t>::type = nullptr> -inline T get(const value& v) + detail::negation< // but not toml::integer + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { - return static_cast(v.cast()); + return static_cast(v.template cast()); } // ============================================================================ // floating point convertible from toml::Float -template class M, template class V> +inline enable_if_t, // T is floating_point - detail::negation> // but not toml::Float - >::value, std::nullptr_t>::type = nullptr> -inline T get(const value& v) + detail::negation< // but not toml::floating + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { - return static_cast(v.cast()); + return static_cast(v.template cast()); } // ============================================================================ // std::string; toml uses its own toml::string, but it should be convertible to // std::string seamlessly -template::value, std::nullptr_t>::type = nullptr> -inline std::string& get(value& v) +template class M, template class V> +inline enable_if_t::value, std::string>& +get(basic_value& v) { - return v.cast().str; + return v.template cast().str; } -template::value, std::nullptr_t>::type = nullptr> -inline std::string const& get(const value& v) +template class M, template class V> +inline enable_if_t::value, std::string> const& +get(const basic_value& v) { - return v.cast().str; + return v.template cast().str; } -template::value, std::nullptr_t>::type = nullptr> -inline std::string get(value&& v) +template class M, template class V> +inline enable_if_t::value, std::string> const& +get(basic_value&& v) { - return std::move(v.cast().str); + return std::move(v.template cast().str); } // ============================================================================ // std::string_view #if __cplusplus >= 201703L -template::value, std::nullptr_t>::type = nullptr> -inline std::string_view get(const value& v) +template class M, template class V> +inline enable_if_t::value, std::string_view> +get(const basic_value& v) { - return std::string_view(v.cast().str); + return std::string_view(v.template cast().str); } #endif // ============================================================================ // std::chrono::duration from toml::local_time. -template::value, std::nullptr_t>::type = nullptr> -inline T get(const value& v) +template class M, template class V> +inline enable_if_t::value, T> +get(const basic_value& v) { return std::chrono::duration_cast( - std::chrono::nanoseconds(v.cast())); + std::chrono::nanoseconds(v.template cast())); } // ============================================================================ // std::chrono::system_clock::time_point from toml::datetime variants -template::value, - std::nullptr_t>::type = nullptr> -inline T get(const value& v) +template class M, template class V> +inline enable_if_t< + std::is_same::value, T> +get(const basic_value& v) { switch(v.type()) { - case value_t::LocalDate: + case value_t::local_date: { return std::chrono::system_clock::time_point( - v.cast()); + v.template cast()); } - case value_t::LocalDatetime: + case value_t::local_datetime: { return std::chrono::system_clock::time_point( - v.cast()); + v.template cast()); + } + case value_t::offset_datetime: + { + return std::chrono::system_clock::time_point( + v.template cast()); } default: { - return std::chrono::system_clock::time_point( - v.cast()); + throw type_error(detail::format_underline("[error] toml::value " + "bad_cast to std::chrono::system_clock::time_point", { + {std::addressof(detail::get_region(v)), + concat_to_string("the actual type is ", v.type())} + })); } } } +/* // ============================================================================ // forward declaration to use this recursively. ignore this and go ahead. @@ -768,6 +799,6 @@ result expect(const toml::table& t, const toml::key& k, return err(e.what()); } } - +*/ } // toml #endif// TOML11_GET From b06ae03deb188c92a1b6d51e1a848caad5f1d96c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 17:53:08 +0900 Subject: [PATCH 021/162] feat: update toml::get for basic_value --- toml/get.hpp | 188 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 77 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 0f5ff92..88ec0eb 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -189,62 +189,87 @@ get(const basic_value& v) } } -/* // ============================================================================ // forward declaration to use this recursively. ignore this and go ahead. -template, // T is container - detail::has_resize_method, // T::resize(N) works - detail::negation> // but not toml::array - >::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template class M, template class V> +enable_if_t, // T is container + detail::has_resize_method, // T::resize(N) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// array-like type with resize(N) method +template class M, template class V> +enable_if_t, // T is container detail::negation>, // no T::resize() exists - detail::negation> // not toml::array - >::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template::value, std::nullptr_t>::type = nullptr> -T get(const value& v); -template, // T is map - detail::negation> // but not toml::table - >::value, std::nullptr_t>::type = nullptr> -T get(const toml::value& v); + detail::negation< // not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); -template>, // not a toml::value - detail::has_from_toml_method, // but has from_toml(toml::value) memfn - std::is_default_constructible // and default constructible - >::value, std::nullptr_t>::type = nullptr> -T get(const toml::value& v); +// std::pair +template class M, template class V> +enable_if_t::value, T> +get(const basic_value&); -template> // not a toml::value - >::value, std::nullptr_t>::type = nullptr, - std::size_t = sizeof(::toml::from) // and has from specialization - > -T get(const toml::value& v); +// std::tuple +template class M, template class V> +enable_if_t::value, T> +get(const basic_value&); + +// map-like classes +template class M, template class V> +enable_if_t, // T is map + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value&); + +// T.from_toml(v) +template class M, template class V> +enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value&); + +// toml::from::from_toml(v) +template class M, template class V, + std::size_t S = sizeof(::toml::into)> +T get(const basic_value&); // ============================================================================ // array-like types; most likely STL container, like std::vector, etc. -template, // T is container - detail::has_resize_method, // T::resize(N) works - detail::negation> // but not toml::array - >::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t, // T is container + detail::has_resize_method, // T::resize(N) works + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using value_type = typename T::value_type; - const auto& ar = v.cast(); - - T container; container.resize(ar.size()); + const auto& ar = v.template cast(); + T container; + container.resize(ar.size()); std::transform(ar.cbegin(), ar.cend(), container.begin(), [](const value& x){return ::toml::get(x);}); return container; @@ -253,15 +278,18 @@ T get(const value& v) // ============================================================================ // array-like types; but does not have resize(); most likely std::array. -template class M, template class V> +enable_if_t, // T is container detail::negation>, // no T::resize() exists - detail::negation> // not toml::array - >::value, std::nullptr_t>::type> -T get(const value& v) + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using value_type = typename T::value_type; - const auto& ar = v.cast(); + const auto& ar = v.template cast(); T container; if(ar.size() != container.size()) @@ -280,14 +308,15 @@ T get(const value& v) // ============================================================================ // std::pair. -template::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t::value, T> +get(const basic_value& v) { using first_type = typename T::first_type; using second_type = typename T::second_type; - const auto& ar = v.cast(); + const auto& ar = v.template cast(); if(ar.size() != 2) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -305,21 +334,20 @@ T get(const value& v) namespace detail { - -template -T get_tuple_impl(const toml::array& a, index_sequence) +template +T get_tuple_impl(const Array& a, index_sequence) { return std::make_tuple( ::toml::get::type>(a.at(I))...); } - } // detail -template::value, std::nullptr_t>::type> -T get(const value& v) +template class M, template class V> +enable_if_t::value, T> +get(const basic_value& v) { - const auto& ar = v.cast(); + const auto& ar = v.template cast(); if(ar.size() != std::tuple_size::value) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -336,11 +364,14 @@ T get(const value& v) // ============================================================================ // map-like types; most likely STL map, like std::map or std::unordered_map. -template, // T is map - detail::negation> // but not toml::table - >::value, std::nullptr_t>::type> -T get(const toml::value& v) +template class M, template class V> +enable_if_t, // T is map + detail::negation< // but not toml::array + detail::is_exact_toml_type>> + >::value, T> +get(const basic_value& v) { using key_type = typename T::key_type; using mapped_type = typename T::mapped_type; @@ -348,36 +379,39 @@ T get(const toml::value& v) "toml::get only supports map type of which key_type is " "convertible from std::string."); T map; - for(const auto& kv : v.cast()) + for(const auto& kv : v.template cast()) { map[key_type(kv.first)] = ::toml::get(kv.second); } return map; } - // ============================================================================ // user-defined, but compatible types. -template>, // not a toml::value - detail::has_from_toml_method, // but has from_toml(toml::value) memfn - std::is_default_constructible // and default constructible - >::value, std::nullptr_t>::type> -T get(const toml::value& v) +template class M, template class V> +enable_if_t>>, + detail::has_from_toml_method, // but has from_toml(toml::value) memfn + std::is_default_constructible // and default constructible + >::value, T> +get(const basic_value& v) { T ud; ud.from_toml(v); return ud; } -template> // not a toml::value - >::value, std::nullptr_t>::type, std::size_t> // and has from -T get(const toml::value& v) +template class M, template class V, + std::size_t> +T get(const basic_value& v) { return ::toml::from::from_toml(v); } +/* // ============================================================================ // find and get From 6de494598a24eb4fb080d93bd6ca6f00779bdaa7 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 18:32:47 +0900 Subject: [PATCH 022/162] fix: remove unused argument to suppress warnings --- toml/comments.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/toml/comments.hpp b/toml/comments.hpp index f43d02a..28ba28e 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -217,28 +217,28 @@ struct empty_iterator }; template -bool operator==(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} +bool operator==(const empty_iterator&, const empty_iterator&) noexcept {return true;} template -bool operator!=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +bool operator!=(const empty_iterator&, const empty_iterator&) noexcept {return false;} template -bool operator< (const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +bool operator< (const empty_iterator&, const empty_iterator&) noexcept {return false;} template -bool operator<=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} +bool operator<=(const empty_iterator&, const empty_iterator&) noexcept {return true;} template -bool operator> (const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return false;} +bool operator> (const empty_iterator&, const empty_iterator&) noexcept {return false;} template -bool operator>=(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return true;} +bool operator>=(const empty_iterator&, const empty_iterator&) noexcept {return true;} template typename empty_iterator::difference_type -operator-(const empty_iterator& lhs, const empty_iterator& rhs) noexcept {return 0;} +operator-(const empty_iterator&, const empty_iterator&) noexcept {return 0;} template empty_iterator -operator+(typename empty_iterator::difference_type lhs, const empty_iterator& rhs) noexcept {return rhs;} +operator+(typename empty_iterator::difference_type, const empty_iterator& rhs) noexcept {return rhs;} template empty_iterator -operator+(const empty_iterator& lhs, typename empty_iterator::difference_type rhs) noexcept {return lhs;} +operator+(const empty_iterator& lhs, typename empty_iterator::difference_type) noexcept {return lhs;} } // detail From cf28c3fb95dac3560aef0551acd7b82c8c69444b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 18:36:49 +0900 Subject: [PATCH 023/162] feat: update toml::find for basic_value --- toml/get.hpp | 129 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 92 insertions(+), 37 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 88ec0eb..627f6aa 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -231,7 +231,7 @@ template class M, template class V> enable_if_t, // T is map - detail::negation< // but not toml::array + detail::negation< // but not toml::table detail::is_exact_toml_type>> >::value, T> get(const basic_value&); @@ -411,52 +411,55 @@ T get(const basic_value& v) return ::toml::from::from_toml(v); } -/* // ============================================================================ // find and get -template -decltype(::toml::get(std::declval())) -find(const toml::table& tab, const toml::key& ky, - std::string tablename = "unknown table") +// for toml::table. +template +enable_if_t::value, decltype( + ::toml::get(std::declval()))> +find(Table& tab, const toml::key& ky, std::string tn = "unknown table") { if(tab.count(ky) == 0) { - throw std::out_of_range(concat_to_string("[error] key \"", ky, - "\" not found in ", tablename)); + throw std::out_of_range(concat_to_string( + "[error] key \"", ky, "\" not found in ", tn)); } return ::toml::get(tab.at(ky)); } -template -decltype(::toml::get(std::declval<::toml::value&>())) -find(toml::table& tab, const toml::key& ky, - std::string tablename = "unknown table") +template +enable_if_t::value, decltype( + ::toml::get(std::declval()))> +find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") { if(tab.count(ky) == 0) { - throw std::out_of_range(concat_to_string("[error] key \"", ky, - "\" not found in ", tablename)); + throw std::out_of_range(concat_to_string( + "[error] key \"", ky, "\" not found in ", tn)); } - return ::toml::get(tab[ky]); + return ::toml::get(tab.at(ky)); } -template -decltype(::toml::get(std::declval<::toml::value&&>())) -find(toml::table&& tab, const toml::key& ky, - std::string tablename = "unknown table") +template +enable_if_t::value, decltype( + ::toml::get(std::declval()))> +find(typename std::remove_reference
&& tab, const toml::key& ky, + std::string tn = "unknown table") { if(tab.count(ky) == 0) { - throw std::out_of_range(concat_to_string("[error] key \"", ky, - "\" not found in ", tablename)); + throw std::out_of_range(concat_to_string( + "[error] key \"", ky, "\" not found in ", tn)); } - return ::toml::get(std::move(tab[ky])); + return ::toml::get(std::move(tab.at(ky))); } -template -decltype(::toml::get(std::declval())) -find(const toml::value& v, const toml::key& ky) +// ---------------------------------------------------------------------------- +// these overloads do not require to set T. and returns value itself. +template class M, template class V> +basic_value const& find(const basic_value& v, const key& ky) { - const auto& tab = ::toml::get(v); + const auto& tab = v.template cast(); if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -464,13 +467,13 @@ find(const toml::value& v, const toml::key& ky) {std::addressof(detail::get_region(v)), "in this table"} })); } - return ::toml::get(tab.at(ky)); + return tab.at(ky); } -template -decltype(::toml::get(std::declval<::toml::value&>())) -find(toml::value& v, const toml::key& ky) +template class M, template class V> +basic_value& find(basic_value& v, const key& ky) { - auto& tab = ::toml::get(v); + const auto& tab = v.template cast(); if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -478,13 +481,13 @@ find(toml::value& v, const toml::key& ky) {std::addressof(detail::get_region(v)), "in this table"} })); } - return ::toml::get(tab.at(ky)); + return tab.at(ky); } -template -decltype(::toml::get(std::declval<::toml::value&&>())) -find(toml::value&& v, const toml::key& ky) +template class M, template class V> +basic_value&& find(basic_value&& v, const key& ky) { - auto tab = ::toml::get(std::move(v)); + auto& tab = v.template cast(); if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -492,9 +495,61 @@ find(toml::value&& v, const toml::key& ky) {std::addressof(detail::get_region(v)), "in this table"} })); } - return ::toml::get(std::move(tab[ky])); + return tab.at(ky); } +// ---------------------------------------------------------------------------- +// find(value, key); + +template class M, template class V> +decltype(::toml::get(std::declval const&>())) +find(const basic_value& v, const key& ky) +{ + const auto& tab = v.template cast(); + if(tab.count(ky) == 0) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); + } + return ::toml::get(tab.at(ky)); +} + +template class M, template class V> +decltype(::toml::get(std::declval&>())) +find(basic_value& v, const key& ky) +{ + const auto& tab = v.template cast(); + if(tab.count(ky) == 0) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); + } + return ::toml::get(tab.at(ky)); +} + +template class M, template class V> +decltype(::toml::get(std::declval&&>())) +find(basic_value&& v, const key& ky) +{ + auto& tab = v.template cast(); + if(tab.count(ky) == 0) + { + throw std::out_of_range(detail::format_underline(concat_to_string( + "[error] key \"", ky, "\" not found"), { + {std::addressof(detail::get_region(v)), "in this table"} + })); + } + return ::toml::get(std::move(tab.at(ky))); +} + +/* // ============================================================================ // get_or(value, fallback) From 3ce1aa31f39654afa65fb367fbda9aaadcff57b4 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 18:47:30 +0900 Subject: [PATCH 024/162] feat: update get_or for basic_value --- toml/get.hpp | 82 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 627f6aa..01dd7c2 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -549,17 +549,16 @@ find(basic_value&& v, const key& ky) return ::toml::get(std::move(tab.at(ky))); } -/* - // ============================================================================ // get_or(value, fallback) // ---------------------------------------------------------------------------- // specialization for the exact toml types (return type becomes lvalue ref) -template::value, std::nullptr_t>::type = nullptr> -T const& get_or(const toml::value& v, const T& opt) +template class M, template class V> +enable_if_t>::value, T> const& +get_or(const basic_value& v, const T& opt) { try { @@ -571,9 +570,10 @@ T const& get_or(const toml::value& v, const T& opt) return opt; } } -template::value, std::nullptr_t>::type = nullptr> -T& get_or(toml::value& v, T& opt) +template class M, template class V> +enable_if_t>::value, T>& +get_or(basic_value& v, T& opt) { try { @@ -585,9 +585,10 @@ T& get_or(toml::value& v, T& opt) return opt; } } -template::value, std::nullptr_t>::type = nullptr> -T&& get_or(toml::value&& v, T&& opt) +template class M, template class V> +enable_if_t>::value, T>&& +get_or(basic_value&& v, T&& opt) { try { @@ -603,53 +604,67 @@ T&& get_or(toml::value&& v, T&& opt) // ---------------------------------------------------------------------------- // specialization for std::string (return type becomes lvalue ref) -template::value, std::nullptr_t>::type = nullptr> -std::string const& get_or(const toml::value& v, const T& opt) +template class M, template class V> +enable_if_t::type>::type, + std::string>::value, std::string> const& +get_or(const basic_value& v, T&& opt) { try { - return get(v); + return v.template cast().str; } catch(...) { return opt; } } -template::value, std::nullptr_t>::type = nullptr> -std::string& get_or(toml::value& v, T& opt) +template class M, template class V> +enable_if_t::type>::type, + std::string>::value, std::string>& +get_or(basic_value& v, T& opt) { try { - return get(v); + return v.template cast().str; } catch(...) { return opt; } } -template::value, std::nullptr_t>::type = nullptr> -std::string get_or(toml::value&& v, T&& opt) +template class M, template class V> +enable_if_t::type>::type, + std::string>::value, std::string> +get_or(basic_value&& v, T&& opt) { try { - return get(v); + return std::move(v.template cast().str); } catch(...) { return opt; } } -template::type>::value, - std::nullptr_t>::type = nullptr> -std::string get_or(const toml::value& v, T&& opt) + +// ---------------------------------------------------------------------------- +// specialization for string literal + +template class M, template class V> +enable_if_t::type>::value, std::string> +get_or(basic_value&& v, T&& opt) { try { - return get(v); + return std::move(v.template cast().str); } catch(...) { @@ -660,12 +675,14 @@ std::string get_or(const toml::value& v, T&& opt) // ---------------------------------------------------------------------------- // others (require type conversion and return type cannot be lvalue reference) -template>, +template class M, template class V> +enable_if_t>>, detail::negation>, detail::negation::type>> - >::value, std::nullptr_t>::type = nullptr> -T get_or(const toml::value& v, T&& opt) + >::value, T> +get_or(const basic_value& v, T&& opt) { try { @@ -678,6 +695,7 @@ T get_or(const toml::value& v, T&& opt) } } +/* // =========================================================================== // find_or(value, key, fallback) From c00eeb18efca9f68e197361824650b9b4ad241c3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:02:01 +0900 Subject: [PATCH 025/162] feat: add meta function that detects toml::basic_value --- toml/traits.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/toml/traits.hpp b/toml/traits.hpp index a994d6d..e2036eb 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -166,6 +166,15 @@ template struct is_container : is_container{}; template struct is_container : is_container{}; template struct is_container : is_container{}; +template +struct is_basic_value: std::false_type{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template struct is_basic_value : is_basic_value{}; +template class M, template class V> +struct is_basic_value<::toml::basic_value>: std::true_type{}; + // --------------------------------------------------------------------------- // C++14 index_sequence From 6d17d5f60f26fba712f1f37fe2593ec1d76a1074 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:02:25 +0900 Subject: [PATCH 026/162] feat: update expect for basic_value --- toml/get.hpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 01dd7c2..92184c3 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -865,12 +865,14 @@ T find_or(const toml::table& tab, const toml::key& ky, T&& opt) if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), std::forward(opt)); } +*/ // ============================================================================ // expect -template -result expect(const toml::value& v) noexcept +template class M, template class V> +result expect(const basic_value& v) noexcept { try { @@ -881,8 +883,10 @@ result expect(const toml::value& v) noexcept return err(e.what()); } } -template -result expect(const toml::value& v, const toml::key& k) noexcept +template class M, template class V> +result +expect(const basic_value& v, const toml::key& k) noexcept { try { @@ -893,9 +897,12 @@ result expect(const toml::value& v, const toml::key& k) noexcept return err(e.what()); } } -template -result expect(const toml::table& t, const toml::key& k, - std::string tablename = "unknown table") noexcept +template +enable_if_t, detail::is_basic_value + >::value, result> +expect(const Table& t, const toml::key& k, + std::string tablename = "unknown table") noexcept { try { @@ -906,6 +913,5 @@ result expect(const toml::table& t, const toml::key& k, return err(e.what()); } } -*/ } // toml #endif// TOML11_GET From 6569c26e1bb4ee35898fe519d1646dcb18d5935c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:04:32 +0900 Subject: [PATCH 027/162] feat: make SFINAE condition strict --- toml/get.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 92184c3..03cf10e 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -416,8 +416,9 @@ T get(const basic_value& v) // for toml::table. template -enable_if_t::value, decltype( - ::toml::get(std::declval()))> +enable_if_t, + detail::is_basic_value>::value, + decltype(::toml::get(std::declval()))> find(Table& tab, const toml::key& ky, std::string tn = "unknown table") { if(tab.count(ky) == 0) @@ -428,8 +429,9 @@ find(Table& tab, const toml::key& ky, std::string tn = "unknown table") return ::toml::get(tab.at(ky)); } template -enable_if_t::value, decltype( - ::toml::get(std::declval()))> +enable_if_t, + detail::is_basic_value>::value, + decltype(::toml::get(std::declval()))> find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") { if(tab.count(ky) == 0) @@ -440,8 +442,9 @@ find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") return ::toml::get(tab.at(ky)); } template -enable_if_t::value, decltype( - ::toml::get(std::declval()))> +enable_if_t, + detail::is_basic_value>::value, + decltype(::toml::get(std::declval()))> find(typename std::remove_reference
&& tab, const toml::key& ky, std::string tn = "unknown table") { From bda337b51f2b1882f5f24a02ad6bca2eeeabea7c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:09:56 +0900 Subject: [PATCH 028/162] feat: support conversion between basic_values --- toml/get.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/toml/get.hpp b/toml/get.hpp index 03cf10e..416aa04 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -68,6 +68,17 @@ get(basic_value&& v) return std::move(v); } +// ============================================================================ +// T == toml::basic_value; basic_value -> basic_value + +template class M, template class V> +inline enable_if_t::value, T> +get(const basic_value& v) +{ + return T(v); +} + // ============================================================================ // integer convertible from toml::Integer From 5ef9890d0cb255d8bf698edb754df2a96555201b Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:22:17 +0900 Subject: [PATCH 029/162] feat: update find_or for basic_value --- toml/get.hpp | 159 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 63 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 416aa04..4e53d2b 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -709,96 +709,106 @@ get_or(const basic_value& v, T&& opt) } } -/* // =========================================================================== // find_or(value, key, fallback) // --------------------------------------------------------------------------- // exact types (return type can be a reference) -template::value, std::nullptr_t>::type = nullptr> -T const& find_or(const toml::value& v, const toml::key& ky, const T& opt) +template class M, template class V> +enable_if_t>::value, T> const& +find_or(const basic_value& v, const key& ky, const T& opt) { if(!v.is_table()) {return opt;} - const auto& tab = toml::get(v); + const auto& tab = v.as_table(); if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), opt); } -template::value, std::nullptr_t>::type = nullptr> -T& find_or(toml::value& v, const toml::key& ky, T& opt) +template class M, template class V> +enable_if_t>::value, T>& +find_or(basic_value& v, const toml::key& ky, T& opt) { if(!v.is_table()) {return opt;} - auto& tab = toml::get(v); + auto& tab = v.as_table(); if(tab.count(ky) == 0) {return opt;} return get_or(tab[ky], opt); } -template::value, std::nullptr_t>::type = nullptr> -T&& find_or(toml::value&& v, const toml::key& ky, T&& opt) +template class M, template class V> +enable_if_t>::value, T>&& +find_or(basic_value&& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} - auto tab = toml::get(std::move(v)); + auto tab = std::move(v).as_table(); if(tab.count(ky) == 0) {return opt;} return get_or(std::move(tab[ky]), std::forward(opt)); } // --------------------------------------------------------------------------- // std::string (return type can be a reference) -template::value, std::nullptr_t>::type = nullptr> -std::string const& find_or(const toml::value& v, const toml::key& ky, const T& opt) + +template class M, template class V> +enable_if_t::value, std::string> const& +find_or(const basic_value& v, const key& ky, const T& opt) { if(!v.is_table()) {return opt;} - const auto& tab = toml::get(v); + const auto& tab = v.as_table(); if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), opt); } -template::value, std::nullptr_t>::type = nullptr> -std::string& find_or(toml::value& v, const toml::key& ky, T& opt) +template class M, template class V> +enable_if_t::value, std::string>& +find_or(basic_value& v, const toml::key& ky, T& opt) { if(!v.is_table()) {return opt;} - auto& tab = toml::get(v); + auto& tab = v.as_table(); if(tab.count(ky) == 0) {return opt;} - return get_or(tab[ky], opt); + return get_or(tab.at(ky), opt); } -template::value, std::nullptr_t>::type = nullptr> -std::string find_or(toml::value&& v, const toml::key& ky, T&& opt) +template class M, template class V> +enable_if_t::value, std::string> +find_or(basic_value&& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} - auto tab = toml::get(std::move(v)); + auto tab = std::move(v).as_table(); if(tab.count(ky) == 0) {return opt;} - return get_or(std::move(tab[ky]), std::forward(opt)); + return get_or(std::move(tab.at(ky)), std::forward(opt)); } // --------------------------------------------------------------------------- // string literal (deduced as std::string) -template class M, template class V> +enable_if_t< detail::is_string_literal::type>::value, - std::nullptr_t>::type = nullptr> -std::string find_or(const toml::value& v, const toml::key& ky, T&& opt) + std::string> +find_or(const basic_value& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} - const auto& tab = toml::get(v); + const auto& tab = v.as_table(); if(tab.count(ky) == 0) {return std::string(opt);} return get_or(tab.at(ky), std::forward(opt)); } // --------------------------------------------------------------------------- // others (require type conversion and return type cannot be lvalue reference) -template>, +template class M, template class V> +enable_if_t>>, detail::negation>, detail::negation::type>> - >::value, std::nullptr_t>::type = nullptr> -T find_or(const toml::value& v, const toml::key& ky, T&& opt) + >::value, T> +find_or(const basic_value& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} - const auto& tab = toml::get(v); + const auto& tab = v.as_table(); if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), std::forward(opt)); } @@ -808,25 +818,34 @@ T find_or(const toml::value& v, const toml::key& ky, T&& opt) // --------------------------------------------------------------------------- // exact types (return type can be a reference) -template::value, std::nullptr_t>::type = nullptr> -T const& find_or(const toml::table& tab, const toml::key& ky, const T& opt) +template +enable_if_t, detail::is_basic_value, + detail::is_exact_toml_type + >::value, T> const& +find_or(const Table& tab, const key& ky, const T& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), opt); } -template::value, std::nullptr_t>::type = nullptr> -T& find_or(toml::table& tab, const toml::key& ky, T& opt) +template +enable_if_t, detail::is_basic_value, + detail::is_exact_toml_type + >::value, T>& +find_or(Table& tab, const key& ky, T& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(tab[ky], opt); } -template::value, std::nullptr_t>::type = nullptr> -T&& find_or(toml::table&& tab, const toml::key& ky, T&& opt) +template +enable_if_t, detail::is_basic_value, + detail::is_exact_toml_type + >::value, T>&& +find_or(typename std::remove_reference
::type&& tab, const key& ky, T&& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(std::move(tab[ky]), std::forward(opt)); @@ -834,23 +853,32 @@ T&& find_or(toml::table&& tab, const toml::key& ky, T&& opt) // --------------------------------------------------------------------------- // std::string (return type can be a reference) -template::value, std::nullptr_t>::type = nullptr> -std::string const& find_or(const toml::table& tab, const toml::key& ky, const T& opt) +template +enable_if_t, detail::is_basic_value, + std::is_same + >::value, std::string> const& +find_or(const Table& tab, const key& ky, const T& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), opt); } -template::value, std::nullptr_t>::type = nullptr> -std::string& find_or(toml::table& tab, const toml::key& ky, T& opt) +template +enable_if_t, detail::is_basic_value, + std::is_same + >::value, std::string>& +find_or(Table& tab, const key& ky, T& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(tab[ky], opt); } -template::value, std::nullptr_t>::type = nullptr> -std::string find_or(toml::table&& tab, const toml::key& ky, T&& opt) +template +enable_if_t, detail::is_basic_value, + std::is_same + >::value, std::string> +find_or(Table&& tab, const key& ky, T&& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(std::move(tab[ky]), std::forward(opt)); @@ -858,10 +886,13 @@ std::string find_or(toml::table&& tab, const toml::key& ky, T&& opt) // --------------------------------------------------------------------------- // string literal (deduced as std::string) -template::type>::value, - std::nullptr_t>::type = nullptr> -std::string find_or(const toml::table& tab, const toml::key& ky, T&& opt) +template +enable_if_t, + detail::is_basic_value, + detail::is_string_literal::type> + >::value, std::string> +find_or(const Table& tab, const key& ky, T&& opt) { if(tab.count(ky) == 0) {return std::string(opt);} return get_or(tab.at(ky), std::forward(opt)); @@ -869,17 +900,19 @@ std::string find_or(const toml::table& tab, const toml::key& ky, T&& opt) // --------------------------------------------------------------------------- // others (require type conversion and return type cannot be lvalue reference) -template>, +template +enable_if_t, + detail::is_basic_value, + detail::negation>, detail::negation>, detail::negation::type>> - >::value, std::nullptr_t>::type = nullptr> -T find_or(const toml::table& tab, const toml::key& ky, T&& opt) + >::value, T> +find_or(const Table& tab, const key& ky, T&& opt) { if(tab.count(ky) == 0) {return opt;} return get_or(tab.at(ky), std::forward(opt)); } -*/ // ============================================================================ // expect From c0b6ca762a5953f4a442922f74ff915a2a3cdfb0 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 19:22:58 +0900 Subject: [PATCH 030/162] feat: :boom: drop from_toml support --- tests/CMakeLists.txt | 1 - tests/test_from_toml.cpp | 63 ----------------------------------- toml/from_toml.hpp | 71 ---------------------------------------- 3 files changed, 135 deletions(-) delete mode 100644 tests/test_from_toml.cpp delete mode 100644 toml/from_toml.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 04ab6c4..23faae6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,7 +24,6 @@ set(TEST_NAMES test_comments test_get test_get_related_func - test_from_toml test_parse_file test_serialize_file test_parse_unicode diff --git a/tests/test_from_toml.cpp b/tests/test_from_toml.cpp deleted file mode 100644 index 45cfac5..0000000 --- a/tests/test_from_toml.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#define BOOST_TEST_MODULE "test_from_toml" -#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST -#include -#else -#define BOOST_TEST_NO_LIB -#include -#endif -#include -#include -#include -#include -#include -#include - -BOOST_AUTO_TEST_CASE(test_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); - } -} - diff --git a/toml/from_toml.hpp b/toml/from_toml.hpp deleted file mode 100644 index bda5a8b..0000000 --- a/toml/from_toml.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright Toru Niina 2017. -// Distributed under the MIT License. -#ifndef TOML11_FROM_TOML_HPP -#define TOML11_FROM_TOML_HPP -#include "get.hpp" - -namespace toml -{ - -template -void from_toml(T& x, const toml::value& v) -{ - x = toml::get::type>(v); - return; -} - -namespace detail -{ - -template -constexpr toml::value_t determine_castable_type() -{ - return check_type() != toml::value_t::Unknown ? check_type() : - toml::detail::is_map::value ? toml::value_t::Table : - toml::detail::is_container::value ? toml::value_t::Array : - toml::value_t::Unknown; -} - -template -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>::type>(); - - static void invoke(std::tuple 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(type_index) == v.type()) - { - from_toml(std::get(tie), v); - return; - } - return from_toml_tie_impl::invoke(tie, v); - } -}; - -template -struct from_toml_tie_impl<0, Ts...> -{ - static void invoke(std::tuple, const toml::value&) - { - return; - } -}; - -} // detail - -template -void from_toml(std::tuple tie, const toml::value& v) -{ - detail::from_toml_tie_impl::invoke(tie, v); - return; -} - - -} // toml -#endif // TOML11_FROM_TOML From 4664f91517e5b670afae7a99bdb10945efc929f7 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 20:40:44 +0900 Subject: [PATCH 031/162] feat: remove unused meta-function alias --- toml/traits.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/toml/traits.hpp b/toml/traits.hpp index e2036eb..408e4a4 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -20,10 +20,6 @@ class basic_value; namespace detail { - -template -using unwrap_t = typename std::decay::type; - // --------------------------------------------------------------------------- // check whether type T is a kind of container/map class From e094d6e85a0517dd9fdc9dc8e0709a4a4727c81d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 20:43:08 +0900 Subject: [PATCH 032/162] refactor: move type alias from get to trait --- toml/get.hpp | 120 ++++++++++++++++++++++++------------------------ toml/traits.hpp | 5 ++ 2 files changed, 66 insertions(+), 59 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 4e53d2b..c2327a4 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -10,16 +10,12 @@ namespace toml { -// C++14 alias -template -using enable_if_t = typename std::enable_if::type; - // ============================================================================ // exact toml::* type template class M, template class V> -enable_if_t>::value, T> & +detail::enable_if_t>::value, T> & get(basic_value& v) { return v.template cast>::value>(); @@ -27,7 +23,7 @@ get(basic_value& v) template class M, template class V> -enable_if_t>::value, T> const& +detail::enable_if_t>::value, T> const& get(const basic_value& v) { return v.template cast>::value>(); @@ -35,7 +31,7 @@ get(const basic_value& v) template class M, template class V> -enable_if_t>::value, T> && +detail::enable_if_t>::value, T> && get(basic_value&& v) { return v.template cast>::value>(); @@ -46,7 +42,7 @@ get(basic_value&& v) template class M, template class V> -inline enable_if_t>::value, T>& +inline detail::enable_if_t>::value, T>& get(basic_value& v) { return v; @@ -54,7 +50,7 @@ get(basic_value& v) template class M, template class V> -inline enable_if_t>::value, T> const& +inline detail::enable_if_t>::value, T> const& get(const basic_value& v) { return v; @@ -62,7 +58,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t>::value, T> && +inline detail::enable_if_t>::value, T> && get(basic_value&& v) { return std::move(v); @@ -73,7 +69,7 @@ get(basic_value&& v) template class M, template class V> -inline enable_if_t::value, T> +inline detail::enable_if_t::value, T> get(const basic_value& v) { return T(v); @@ -84,7 +80,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t, // T is integral detail::negation>, // but not bool detail::negation< // but not toml::integer @@ -100,7 +96,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t, // T is floating_point detail::negation< // but not toml::floating detail::is_exact_toml_type>> @@ -116,7 +112,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t::value, std::string>& +inline detail::enable_if_t::value, std::string>& get(basic_value& v) { return v.template cast().str; @@ -124,7 +120,7 @@ get(basic_value& v) template class M, template class V> -inline enable_if_t::value, std::string> const& +inline detail::enable_if_t::value, std::string> const& get(const basic_value& v) { return v.template cast().str; @@ -132,7 +128,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t::value, std::string> const& +inline detail::enable_if_t::value, std::string> const& get(basic_value&& v) { return std::move(v.template cast().str); @@ -144,7 +140,7 @@ get(basic_value&& v) #if __cplusplus >= 201703L template class M, template class V> -inline enable_if_t::value, std::string_view> +inline detail::enable_if_t::value, std::string_view> get(const basic_value& v) { return std::string_view(v.template cast().str); @@ -156,7 +152,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t::value, T> +inline detail::enable_if_t::value, T> get(const basic_value& v) { return std::chrono::duration_cast( @@ -168,7 +164,7 @@ get(const basic_value& v) template class M, template class V> -inline enable_if_t< +inline detail::enable_if_t< std::is_same::value, T> get(const basic_value& v) { @@ -206,7 +202,7 @@ get(const basic_value& v) // array-like type with resize(N) method template class M, template class V> -enable_if_t, // T is container detail::has_resize_method, // T::resize(N) works detail::negation< // but not toml::array @@ -217,7 +213,7 @@ get(const basic_value&); // array-like type with resize(N) method template class M, template class V> -enable_if_t, // T is container detail::negation>, // no T::resize() exists detail::negation< // not toml::array @@ -228,19 +224,19 @@ get(const basic_value&); // std::pair template class M, template class V> -enable_if_t::value, T> +detail::enable_if_t::value, T> get(const basic_value&); // std::tuple template class M, template class V> -enable_if_t::value, T> +detail::enable_if_t::value, T> get(const basic_value&); // map-like classes template class M, template class V> -enable_if_t, // T is map detail::negation< // but not toml::table detail::is_exact_toml_type>> @@ -250,7 +246,7 @@ get(const basic_value&); // T.from_toml(v) template class M, template class V> -enable_if_t>>, detail::has_from_toml_method, // but has from_toml(toml::value) @@ -269,7 +265,7 @@ T get(const basic_value&); template class M, template class V> -enable_if_t, // T is container detail::has_resize_method, // T::resize(N) works detail::negation< // but not toml::array @@ -291,7 +287,7 @@ get(const basic_value& v) template class M, template class V> -enable_if_t, // T is container detail::negation>, // no T::resize() exists detail::negation< // but not toml::array @@ -321,7 +317,7 @@ get(const basic_value& v) template class M, template class V> -enable_if_t::value, T> +detail::enable_if_t::value, T> get(const basic_value& v) { using first_type = typename T::first_type; @@ -355,7 +351,7 @@ T get_tuple_impl(const Array& a, index_sequence) template class M, template class V> -enable_if_t::value, T> +detail::enable_if_t::value, T> get(const basic_value& v) { const auto& ar = v.template cast(); @@ -377,7 +373,7 @@ get(const basic_value& v) template class M, template class V> -enable_if_t, // T is map detail::negation< // but not toml::array detail::is_exact_toml_type>> @@ -402,7 +398,7 @@ get(const basic_value& v) template class M, template class V> -enable_if_t>>, detail::has_from_toml_method, // but has from_toml(toml::value) memfn @@ -427,7 +423,7 @@ T get(const basic_value& v) // for toml::table. template -enable_if_t, +detail::enable_if_t, detail::is_basic_value>::value, decltype(::toml::get(std::declval()))> find(Table& tab, const toml::key& ky, std::string tn = "unknown table") @@ -440,7 +436,7 @@ find(Table& tab, const toml::key& ky, std::string tn = "unknown table") return ::toml::get(tab.at(ky)); } template -enable_if_t, +detail::enable_if_t, detail::is_basic_value>::value, decltype(::toml::get(std::declval()))> find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") @@ -453,7 +449,7 @@ find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") return ::toml::get(tab.at(ky)); } template -enable_if_t, +detail::enable_if_t, detail::is_basic_value>::value, decltype(::toml::get(std::declval()))> find(typename std::remove_reference
&& tab, const toml::key& ky, @@ -571,7 +567,8 @@ find(basic_value&& v, const key& ky) template class M, template class V> -enable_if_t>::value, T> const& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T> const& get_or(const basic_value& v, const T& opt) { try @@ -586,7 +583,8 @@ get_or(const basic_value& v, const T& opt) } template class M, template class V> -enable_if_t>::value, T>& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>& get_or(basic_value& v, T& opt) { try @@ -601,7 +599,8 @@ get_or(basic_value& v, T& opt) } template class M, template class V> -enable_if_t>::value, T>&& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>&& get_or(basic_value&& v, T&& opt) { try @@ -620,7 +619,7 @@ get_or(basic_value&& v, T&& opt) template class M, template class V> -enable_if_t::type>::type, std::string>::value, std::string> const& get_or(const basic_value& v, T&& opt) @@ -636,7 +635,7 @@ get_or(const basic_value& v, T&& opt) } template class M, template class V> -enable_if_t::type>::type, std::string>::value, std::string>& get_or(basic_value& v, T& opt) @@ -652,7 +651,7 @@ get_or(basic_value& v, T& opt) } template class M, template class V> -enable_if_t::type>::type, std::string>::value, std::string> get_or(basic_value&& v, T&& opt) @@ -672,7 +671,7 @@ get_or(basic_value&& v, T&& opt) template class M, template class V> -enable_if_t::type>::value, std::string> get_or(basic_value&& v, T&& opt) { @@ -691,7 +690,7 @@ get_or(basic_value&& v, T&& opt) template class M, template class V> -enable_if_t>>, detail::negation>, detail::negation::type>> @@ -716,7 +715,8 @@ get_or(const basic_value& v, T&& opt) // exact types (return type can be a reference) template class M, template class V> -enable_if_t>::value, T> const& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T> const& find_or(const basic_value& v, const key& ky, const T& opt) { if(!v.is_table()) {return opt;} @@ -727,7 +727,8 @@ find_or(const basic_value& v, const key& ky, const T& opt) template class M, template class V> -enable_if_t>::value, T>& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>& find_or(basic_value& v, const toml::key& ky, T& opt) { if(!v.is_table()) {return opt;} @@ -738,7 +739,8 @@ find_or(basic_value& v, const toml::key& ky, T& opt) template class M, template class V> -enable_if_t>::value, T>&& +detail::enable_if_t< + detail::is_exact_toml_type>::value, T>&& find_or(basic_value&& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} @@ -752,7 +754,7 @@ find_or(basic_value&& v, const toml::key& ky, T&& opt) template class M, template class V> -enable_if_t::value, std::string> const& +detail::enable_if_t::value, std::string> const& find_or(const basic_value& v, const key& ky, const T& opt) { if(!v.is_table()) {return opt;} @@ -762,7 +764,7 @@ find_or(const basic_value& v, const key& ky, const T& opt) } template class M, template class V> -enable_if_t::value, std::string>& +detail::enable_if_t::value, std::string>& find_or(basic_value& v, const toml::key& ky, T& opt) { if(!v.is_table()) {return opt;} @@ -772,7 +774,7 @@ find_or(basic_value& v, const toml::key& ky, T& opt) } template class M, template class V> -enable_if_t::value, std::string> +detail::enable_if_t::value, std::string> find_or(basic_value&& v, const toml::key& ky, T&& opt) { if(!v.is_table()) {return opt;} @@ -785,7 +787,7 @@ find_or(basic_value&& v, const toml::key& ky, T&& opt) // string literal (deduced as std::string) template class M, template class V> -enable_if_t< +detail::enable_if_t< detail::is_string_literal::type>::value, std::string> find_or(const basic_value& v, const toml::key& ky, T&& opt) @@ -800,7 +802,7 @@ find_or(const basic_value& v, const toml::key& ky, T&& opt) // others (require type conversion and return type cannot be lvalue reference) template class M, template class V> -enable_if_t>>, detail::negation>, detail::negation::type>> @@ -819,7 +821,7 @@ find_or(const basic_value& v, const toml::key& ky, T&& opt) // --------------------------------------------------------------------------- // exact types (return type can be a reference) template -enable_if_t, detail::is_basic_value, detail::is_exact_toml_type >::value, T> const& @@ -830,7 +832,7 @@ find_or(const Table& tab, const key& ky, const T& opt) } template -enable_if_t, detail::is_basic_value, detail::is_exact_toml_type >::value, T>& @@ -841,7 +843,7 @@ find_or(Table& tab, const key& ky, T& opt) } template -enable_if_t, detail::is_basic_value, detail::is_exact_toml_type >::value, T>&& @@ -854,7 +856,7 @@ find_or(typename std::remove_reference
::type&& tab, const key& ky, T&& op // --------------------------------------------------------------------------- // std::string (return type can be a reference) template -enable_if_t, detail::is_basic_value, std::is_same >::value, std::string> const& @@ -864,7 +866,7 @@ find_or(const Table& tab, const key& ky, const T& opt) return get_or(tab.at(ky), opt); } template -enable_if_t, detail::is_basic_value, std::is_same >::value, std::string>& @@ -874,7 +876,7 @@ find_or(Table& tab, const key& ky, T& opt) return get_or(tab[ky], opt); } template -enable_if_t, detail::is_basic_value, std::is_same >::value, std::string> @@ -887,7 +889,7 @@ find_or(Table&& tab, const key& ky, T&& opt) // --------------------------------------------------------------------------- // string literal (deduced as std::string) template -enable_if_t, detail::is_basic_value, detail::is_string_literal::type> @@ -901,7 +903,7 @@ find_or(const Table& tab, const key& ky, T&& opt) // --------------------------------------------------------------------------- // others (require type conversion and return type cannot be lvalue reference) template -enable_if_t, detail::is_basic_value, detail::negation>, @@ -945,7 +947,7 @@ expect(const basic_value& v, const toml::key& k) noexcept } } template -enable_if_t, detail::is_basic_value >::value, result> expect(const Table& t, const toml::key& k, diff --git a/toml/traits.hpp b/toml/traits.hpp index 408e4a4..cbc1a2c 100644 --- a/toml/traits.hpp +++ b/toml/traits.hpp @@ -197,6 +197,11 @@ struct index_sequence_maker<0> template using make_index_sequence = typename index_sequence_maker::type; +// --------------------------------------------------------------------------- +// C++14 enable_if_t +template +using enable_if_t = typename std::enable_if::type; + // --------------------------------------------------------------------------- // return_type_of_t From 8456186eac96acaad2d62c54900774cd5187791d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:34:57 +0900 Subject: [PATCH 033/162] fix: remove inclusion of removed file --- toml.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/toml.hpp b/toml.hpp index fde2a3c..2182df1 100644 --- a/toml.hpp +++ b/toml.hpp @@ -36,7 +36,6 @@ #include "toml/parser.hpp" #include "toml/literal.hpp" #include "toml/serializer.hpp" -#include "toml/from_toml.hpp" #include "toml/get.hpp" #endif// TOML_FOR_MODERN_CPP From 7d34436535f2f7fca41692c52698dae652f7859f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:36:09 +0900 Subject: [PATCH 034/162] test: update value_t::* names in the test code --- tests/test_value.cpp | 502 +++++++++++++++++++++---------------------- 1 file changed, 251 insertions(+), 251 deletions(-) diff --git a/tests/test_value.cpp b/tests/test_value.cpp index 0471291..f90045f 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -19,34 +19,34 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) toml::value v1(true); toml::value v2(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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); + BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v2.cast(), false); BOOST_CHECK_EQUAL(v1.as_boolean(), true); BOOST_CHECK_EQUAL(v2.as_boolean(), false); v1 = false; v2 = true; - 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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), false); - BOOST_CHECK_EQUAL(v2.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), false); + BOOST_CHECK_EQUAL(v2.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), false); BOOST_CHECK_EQUAL(v2.as_boolean(), true); @@ -55,51 +55,51 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) BOOST_CHECK(v3 == v1); BOOST_CHECK(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Boolean); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::Boolean); - BOOST_CHECK(v3.is(toml::value_t::Boolean)); - BOOST_CHECK(v4.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::boolean); + BOOST_CHECK_EQUAL(v4.type(), toml::value_t::boolean); + BOOST_CHECK(v3.is(toml::value_t::boolean)); + BOOST_CHECK(v4.is(toml::value_t::boolean)); BOOST_CHECK(v3.is()); BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_boolean()); BOOST_CHECK(v4.is_boolean()); - BOOST_CHECK_EQUAL(v3.cast(), false); - BOOST_CHECK_EQUAL(v4.cast(), true); + BOOST_CHECK_EQUAL(v3.cast(), false); + BOOST_CHECK_EQUAL(v4.cast(), true); BOOST_CHECK_EQUAL(v3.as_boolean(), false); BOOST_CHECK_EQUAL(v4.as_boolean(), true); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::Boolean); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::Boolean); - BOOST_CHECK(v5.is(toml::value_t::Boolean)); - BOOST_CHECK(v6.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v5.type(), toml::value_t::boolean); + BOOST_CHECK_EQUAL(v6.type(), toml::value_t::boolean); + BOOST_CHECK(v5.is(toml::value_t::boolean)); + BOOST_CHECK(v6.is(toml::value_t::boolean)); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); BOOST_CHECK(v3.is_boolean()); BOOST_CHECK(v4.is_boolean()); - BOOST_CHECK_EQUAL(v5.cast(), false); - BOOST_CHECK_EQUAL(v6.cast(), true); + BOOST_CHECK_EQUAL(v5.cast(), false); + BOOST_CHECK_EQUAL(v6.cast(), true); BOOST_CHECK_EQUAL(v5.as_boolean(), false); BOOST_CHECK_EQUAL(v6.as_boolean(), true); v1 = 42; v2 = 3.14; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Integer); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Float); - BOOST_CHECK(v1.is(toml::value_t::Integer)); - BOOST_CHECK(v2.is(toml::value_t::Float)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::integer); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); + BOOST_CHECK(v1.is(toml::value_t::integer)); + BOOST_CHECK(v2.is(toml::value_t::floating)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_float()); - BOOST_CHECK_EQUAL(v1.cast(), 42); - BOOST_CHECK_EQUAL(v2.cast(), 3.14); + BOOST_CHECK_EQUAL(v1.cast(), 42); + BOOST_CHECK_EQUAL(v2.cast(), 3.14); BOOST_CHECK_EQUAL(v1.as_integer(), 42); BOOST_CHECK_EQUAL(v2.as_float(), 3.14); } @@ -109,34 +109,34 @@ BOOST_AUTO_TEST_CASE(test_value_integer) toml::value v1(-42); toml::value v2(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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_integer()); - BOOST_CHECK_EQUAL(v1.cast(), -42); - BOOST_CHECK_EQUAL(v2.cast(), 42u); + BOOST_CHECK_EQUAL(v1.cast(), -42); + BOOST_CHECK_EQUAL(v2.cast(), 42u); BOOST_CHECK_EQUAL(v1.as_integer(), -42); BOOST_CHECK_EQUAL(v2.as_integer(), 42u); v1 = 54; v2 = -54; - 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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_integer()); - BOOST_CHECK_EQUAL(v1.cast(), 54); - BOOST_CHECK_EQUAL(v2.cast(), -54); + BOOST_CHECK_EQUAL(v1.cast(), 54); + BOOST_CHECK_EQUAL(v2.cast(), -54); BOOST_CHECK_EQUAL(v1.as_integer(), 54); BOOST_CHECK_EQUAL(v2.as_integer(), -54); @@ -145,51 +145,51 @@ BOOST_AUTO_TEST_CASE(test_value_integer) BOOST_CHECK(v3 == v1); BOOST_CHECK(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Integer); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::Integer); - BOOST_CHECK(v3.is(toml::value_t::Integer)); - BOOST_CHECK(v4.is(toml::value_t::Integer)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::integer); + BOOST_CHECK_EQUAL(v4.type(), toml::value_t::integer); + BOOST_CHECK(v3.is(toml::value_t::integer)); + BOOST_CHECK(v4.is(toml::value_t::integer)); BOOST_CHECK(v3.is()); BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_integer()); BOOST_CHECK(v4.is_integer()); - BOOST_CHECK_EQUAL(v3.cast(), 54); - BOOST_CHECK_EQUAL(v4.cast(), -54); + BOOST_CHECK_EQUAL(v3.cast(), 54); + BOOST_CHECK_EQUAL(v4.cast(), -54); BOOST_CHECK_EQUAL(v3.as_integer(), 54); BOOST_CHECK_EQUAL(v4.as_integer(), -54); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::Integer); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::Integer); - BOOST_CHECK(v5.is(toml::value_t::Integer)); - BOOST_CHECK(v6.is(toml::value_t::Integer)); + BOOST_CHECK_EQUAL(v5.type(), toml::value_t::integer); + BOOST_CHECK_EQUAL(v6.type(), toml::value_t::integer); + BOOST_CHECK(v5.is(toml::value_t::integer)); + BOOST_CHECK(v6.is(toml::value_t::integer)); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); BOOST_CHECK(v5.is_integer()); BOOST_CHECK(v6.is_integer()); - BOOST_CHECK_EQUAL(v5.cast(), 54); - BOOST_CHECK_EQUAL(v6.cast(), -54); + BOOST_CHECK_EQUAL(v5.cast(), 54); + BOOST_CHECK_EQUAL(v6.cast(), -54); BOOST_CHECK_EQUAL(v5.as_integer(), 54); BOOST_CHECK_EQUAL(v6.as_integer(), -54); v1 = true; v2 = 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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); + BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v2.cast(), false); BOOST_CHECK_EQUAL(v1.as_boolean(), true); BOOST_CHECK_EQUAL(v2.as_boolean(), false); } @@ -199,34 +199,34 @@ BOOST_AUTO_TEST_CASE(test_value_float) toml::value v1(3.14); toml::value v2(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_EQUAL(v1.type(), toml::value_t::floating); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); + BOOST_CHECK(v1.is(toml::value_t::floating)); + BOOST_CHECK(v2.is(toml::value_t::floating)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_float()); BOOST_CHECK(v2.is_float()); - BOOST_CHECK_EQUAL (v1.cast(), 3.14); - BOOST_CHECK_CLOSE_FRACTION(v2.cast(), 3.14, 1e-2); + BOOST_CHECK_EQUAL (v1.cast(), 3.14); + BOOST_CHECK_CLOSE_FRACTION(v2.cast(), 3.14, 1e-2); BOOST_CHECK_EQUAL (v1.as_float(), 3.14); BOOST_CHECK_CLOSE_FRACTION(v2.as_float(), 3.14, 1e-2); v1 = 2.718f; v2 = 2.718; - 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_EQUAL(v1.type(), toml::value_t::floating); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); + BOOST_CHECK(v1.is(toml::value_t::floating)); + BOOST_CHECK(v2.is(toml::value_t::floating)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_float()); BOOST_CHECK(v2.is_float()); - BOOST_CHECK_CLOSE_FRACTION(v1.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v2.cast(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v1.cast(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v2.cast(), 2.718); BOOST_CHECK_CLOSE_FRACTION(v1.as_float(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v2.as_float(), 2.718); @@ -235,51 +235,51 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK(v3 == v1); BOOST_CHECK(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Float); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::Float); - BOOST_CHECK(v3.is(toml::value_t::Float)); - BOOST_CHECK(v4.is(toml::value_t::Float)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::floating); + BOOST_CHECK_EQUAL(v4.type(), toml::value_t::floating); + BOOST_CHECK(v3.is(toml::value_t::floating)); + BOOST_CHECK(v4.is(toml::value_t::floating)); BOOST_CHECK(v3.is()); BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_float()); BOOST_CHECK(v4.is_float()); - BOOST_CHECK_CLOSE_FRACTION(v3.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v4.cast(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v3.cast(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v4.cast(), 2.718); BOOST_CHECK_CLOSE_FRACTION(v3.as_float(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v4.as_float(), 2.718); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::Float); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::Float); - BOOST_CHECK(v5.is(toml::value_t::Float)); - BOOST_CHECK(v6.is(toml::value_t::Float)); + BOOST_CHECK_EQUAL(v5.type(), toml::value_t::floating); + BOOST_CHECK_EQUAL(v6.type(), toml::value_t::floating); + BOOST_CHECK(v5.is(toml::value_t::floating)); + BOOST_CHECK(v6.is(toml::value_t::floating)); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); BOOST_CHECK(v5.is_float()); BOOST_CHECK(v6.is_float()); - BOOST_CHECK_CLOSE_FRACTION(v5.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v6.cast(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v5.cast(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v6.cast(), 2.718); BOOST_CHECK_CLOSE_FRACTION(v5.as_float(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v6.as_float(), 2.718); v1 = true; v2 = 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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); + BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v2.cast(), false); BOOST_CHECK_EQUAL(v1.as_boolean(), true); BOOST_CHECK_EQUAL(v2.as_boolean(), false); } @@ -290,12 +290,12 @@ BOOST_AUTO_TEST_CASE(test_value_string) toml::value v2(std::string("foo"), toml::string_t::literal); toml::value v3("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_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()); BOOST_CHECK(v2.is()); BOOST_CHECK(v3.is()); @@ -303,9 +303,9 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v2.is_string()); BOOST_CHECK(v3.is_string()); - BOOST_CHECK_EQUAL(v1.cast(), "foo"); - BOOST_CHECK_EQUAL(v2.cast(), "foo"); - BOOST_CHECK_EQUAL(v3.cast(), "foo"); + BOOST_CHECK_EQUAL(v1.cast(), "foo"); + BOOST_CHECK_EQUAL(v2.cast(), "foo"); + BOOST_CHECK_EQUAL(v3.cast(), "foo"); BOOST_CHECK_EQUAL(v1.as_string(), "foo"); BOOST_CHECK_EQUAL(v2.as_string(), "foo"); BOOST_CHECK_EQUAL(v3.as_string(), "foo"); @@ -315,19 +315,19 @@ BOOST_AUTO_TEST_CASE(test_value_string) v2 = "bar"; v3 = "bar"; - 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_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_string()); BOOST_CHECK(v2.is_string()); BOOST_CHECK(v3.is_string()); - BOOST_CHECK_EQUAL(v1.cast(), "bar"); - BOOST_CHECK_EQUAL(v2.cast(), "bar"); - BOOST_CHECK_EQUAL(v3.cast(), "bar"); + BOOST_CHECK_EQUAL(v1.cast(), "bar"); + BOOST_CHECK_EQUAL(v2.cast(), "bar"); + BOOST_CHECK_EQUAL(v3.cast(), "bar"); BOOST_CHECK_EQUAL(v1.as_string(), "bar"); BOOST_CHECK_EQUAL(v2.as_string(), "bar"); BOOST_CHECK_EQUAL(v3.as_string(), "bar"); @@ -340,12 +340,12 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v5 == v2); BOOST_CHECK(v6 == v3); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::String); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::String); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::String); - BOOST_CHECK(v4.is(toml::value_t::String)); - BOOST_CHECK(v5.is(toml::value_t::String)); - BOOST_CHECK(v6.is(toml::value_t::String)); + BOOST_CHECK_EQUAL(v4.type(), toml::value_t::string); + BOOST_CHECK_EQUAL(v5.type(), toml::value_t::string); + BOOST_CHECK_EQUAL(v6.type(), toml::value_t::string); + BOOST_CHECK(v4.is(toml::value_t::string)); + BOOST_CHECK(v5.is(toml::value_t::string)); + BOOST_CHECK(v6.is(toml::value_t::string)); BOOST_CHECK(v4.is()); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); @@ -353,24 +353,24 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v5.is_string()); BOOST_CHECK(v6.is_string()); - BOOST_CHECK_EQUAL(v4.cast(), "bar"); - BOOST_CHECK_EQUAL(v5.cast(), "bar"); - BOOST_CHECK_EQUAL(v6.cast(), "bar"); + BOOST_CHECK_EQUAL(v4.cast(), "bar"); + BOOST_CHECK_EQUAL(v5.cast(), "bar"); + BOOST_CHECK_EQUAL(v6.cast(), "bar"); BOOST_CHECK_EQUAL(v4.as_string(), "bar"); BOOST_CHECK_EQUAL(v5.as_string(), "bar"); BOOST_CHECK_EQUAL(v6.as_string(), "bar"); - v4.cast().str.at(2) = 'z'; - v5.cast().str.at(2) = 'z'; - v6.cast().str.at(2) = 'z'; + v4.cast().str.at(2) = 'z'; + v5.cast().str.at(2) = 'z'; + v6.cast().str.at(2) = 'z'; - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::String); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::String); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::String); - BOOST_CHECK(v4.is(toml::value_t::String)); - BOOST_CHECK(v5.is(toml::value_t::String)); - BOOST_CHECK(v6.is(toml::value_t::String)); + BOOST_CHECK_EQUAL(v4.type(), toml::value_t::string); + BOOST_CHECK_EQUAL(v5.type(), toml::value_t::string); + BOOST_CHECK_EQUAL(v6.type(), toml::value_t::string); + BOOST_CHECK(v4.is(toml::value_t::string)); + BOOST_CHECK(v5.is(toml::value_t::string)); + BOOST_CHECK(v6.is(toml::value_t::string)); BOOST_CHECK(v4.is()); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); @@ -386,12 +386,12 @@ BOOST_AUTO_TEST_CASE(test_value_string) v2 = true; v3 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Boolean); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); - BOOST_CHECK(v2.is(toml::value_t::Boolean)); - BOOST_CHECK(v3.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::boolean); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); + BOOST_CHECK(v2.is(toml::value_t::boolean)); + BOOST_CHECK(v3.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v3.is()); @@ -399,9 +399,9 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v2.is_boolean()); BOOST_CHECK(v3.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), true); - BOOST_CHECK_EQUAL(v3.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v2.cast(), true); + BOOST_CHECK_EQUAL(v3.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); BOOST_CHECK_EQUAL(v2.as_boolean(), true); BOOST_CHECK_EQUAL(v3.as_boolean(), true); @@ -412,17 +412,17 @@ BOOST_AUTO_TEST_CASE(test_value_string) toml::value v7(sv); toml::value v8(sv, toml::string_t::literal); - BOOST_CHECK_EQUAL(v7.type(), toml::value_t::String); - BOOST_CHECK_EQUAL(v8.type(), toml::value_t::String); - BOOST_CHECK(v7.is(toml::value_t::String)); - BOOST_CHECK(v8.is(toml::value_t::String)); + BOOST_CHECK_EQUAL(v7.type(), toml::value_t::string); + BOOST_CHECK_EQUAL(v8.type(), toml::value_t::string); + BOOST_CHECK(v7.is(toml::value_t::string)); + BOOST_CHECK(v8.is(toml::value_t::string)); BOOST_CHECK(v7.is()); BOOST_CHECK(v8.is()); BOOST_CHECK(v7.is_string()); BOOST_CHECK(v8.is_string()); - BOOST_CHECK_EQUAL(v7.cast(), "foo"); - BOOST_CHECK_EQUAL(v8.cast(), "foo"); + BOOST_CHECK_EQUAL(v7.cast(), "foo"); + BOOST_CHECK_EQUAL(v8.cast(), "foo"); #endif } @@ -430,24 +430,24 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) { toml::value v1(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_EQUAL(v1.type(), toml::value_t::local_date); + BOOST_CHECK(v1.is(toml::value_t::local_date)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_date()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_date(2018, toml::month_t::Jan, 31)); BOOST_CHECK_EQUAL(v1.as_local_date(), toml::local_date(2018, toml::month_t::Jan, 31)); v1 = toml::local_date(2018, toml::month_t::Apr, 1); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalDate); - BOOST_CHECK(v1.is(toml::value_t::LocalDate)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_date); + BOOST_CHECK(v1.is(toml::value_t::local_date)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_date()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_date(2018, toml::month_t::Apr, 1)); BOOST_CHECK_EQUAL(v1.as_local_date(), toml::local_date(2018, toml::month_t::Apr, 1)); @@ -455,22 +455,22 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) toml::value v2(v1); BOOST_CHECK(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::LocalDate); - BOOST_CHECK(v2.is(toml::value_t::LocalDate)); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_date); + BOOST_CHECK(v2.is(toml::value_t::local_date)); BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_local_date()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_CHECK_EQUAL(v2.cast(), toml::local_date(2018, toml::month_t::Apr, 1)); BOOST_CHECK_EQUAL(v2.as_local_date(), toml::local_date(2018, toml::month_t::Apr, 1)); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -480,37 +480,37 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) toml::value v2(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_EQUAL(v1.type(), toml::value_t::local_time); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_time); + BOOST_CHECK(v1.is(toml::value_t::local_time)); + BOOST_CHECK(v2.is(toml::value_t::local_time)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_local_time()); BOOST_CHECK(v2.is_local_time()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_time(12, 30, 45)); BOOST_CHECK_EQUAL(v1.as_local_time(), toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_CHECK_EQUAL(v2.cast(), toml::local_time(12, 30, 45)); BOOST_CHECK_EQUAL(v2.as_local_time(), toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v1.cast(), - v2.cast()); + BOOST_CHECK_EQUAL(v1.cast(), + v2.cast()); BOOST_CHECK_EQUAL(v1.as_local_time(), v2.as_local_time()); v1 = toml::local_time(1, 30, 0, /*ms*/ 100, /*us*/ 0); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalTime); - BOOST_CHECK(v1.is(toml::value_t::LocalTime)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_time); + BOOST_CHECK(v1.is(toml::value_t::local_time)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_time()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_time(1, 30, 0, 100, 0)); BOOST_CHECK_EQUAL(v1.as_local_time(), toml::local_time(1, 30, 0, 100, 0)); @@ -518,22 +518,22 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) toml::value v3(v1); BOOST_CHECK(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::LocalTime); - BOOST_CHECK(v3.is(toml::value_t::LocalTime)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::local_time); + BOOST_CHECK(v3.is(toml::value_t::local_time)); BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_local_time()); - BOOST_CHECK_EQUAL(v3.cast(), + BOOST_CHECK_EQUAL(v3.cast(), toml::local_time(1, 30, 0, 100, 0)); BOOST_CHECK_EQUAL(v3.as_local_time(), toml::local_time(1, 30, 0, 100, 0)); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -544,12 +544,12 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) 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_EQUAL(v1.type(), toml::value_t::local_datetime); + BOOST_CHECK(v1.is(toml::value_t::local_datetime)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45))); @@ -562,12 +562,12 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::LocalDatetime); - BOOST_CHECK(v1.is(toml::value_t::LocalDatetime)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_datetime); + BOOST_CHECK(v1.is(toml::value_t::local_datetime)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); @@ -579,12 +579,12 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) toml::value v2(v1); BOOST_CHECK(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::LocalDatetime); - BOOST_CHECK(v2.is(toml::value_t::LocalDatetime)); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_datetime); + BOOST_CHECK(v2.is(toml::value_t::local_datetime)); BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_local_datetime()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_CHECK_EQUAL(v2.cast(), toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); @@ -595,11 +595,11 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -611,12 +611,12 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::time_offset(9, 0) )); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::OffsetDatetime); - BOOST_CHECK(v1.is(toml::value_t::OffsetDatetime)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); + BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_offset_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::offset_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45), @@ -634,12 +634,12 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::local_time(1, 15, 30), toml::time_offset(9, 0)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::OffsetDatetime); - BOOST_CHECK(v1.is(toml::value_t::OffsetDatetime)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); + BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_offset_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_CHECK_EQUAL(v1.cast(), toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), @@ -654,12 +654,12 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::value v2(v1); BOOST_CHECK(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::OffsetDatetime); - BOOST_CHECK(v2.is(toml::value_t::OffsetDatetime)); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::offset_datetime); + BOOST_CHECK(v2.is(toml::value_t::offset_datetime)); BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_offset_datetime()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_CHECK_EQUAL(v2.cast(), toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), @@ -671,11 +671,11 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::time_offset(9, 0))); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -685,21 +685,21 @@ BOOST_AUTO_TEST_CASE(test_value_array) toml::value v1(v); toml::value v2{6,7,8,9,0}; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Array); - BOOST_CHECK(v1.is(toml::value_t::Array)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::array); + BOOST_CHECK(v1.is(toml::value_t::array)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_array()); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Array); - BOOST_CHECK(v2.is(toml::value_t::Array)); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); + BOOST_CHECK(v2.is(toml::value_t::array)); BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_array()); - BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 1); - BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 2); - BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 3); - BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 4); - BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 5); + BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 1); + BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 2); + BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 3); + BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 4); + BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 5); BOOST_CHECK_EQUAL(v1.as_array().at(0).as_integer(), 1); BOOST_CHECK_EQUAL(v1.as_array().at(1).as_integer(), 2); BOOST_CHECK_EQUAL(v1.as_array().at(2).as_integer(), 3); @@ -707,30 +707,30 @@ BOOST_AUTO_TEST_CASE(test_value_array) BOOST_CHECK_EQUAL(v1.as_array().at(4).as_integer(), 5); - BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 0); + BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 6); + BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 7); + BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 8); + BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 9); + BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 0); v1 = {6,7,8,9,0}; v2 = v; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Array); - BOOST_CHECK(v1.is(toml::value_t::Array)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::array); + BOOST_CHECK(v1.is(toml::value_t::array)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_array()); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::Array); - BOOST_CHECK(v2.is(toml::value_t::Array)); + BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); + BOOST_CHECK(v2.is(toml::value_t::array)); BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_array()); - BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 0); + BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 6); + BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 7); + BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 8); + BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 9); + BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 0); BOOST_CHECK_EQUAL(v1.as_array().at(0).as_integer(), 6); BOOST_CHECK_EQUAL(v1.as_array().at(1).as_integer(), 7); BOOST_CHECK_EQUAL(v1.as_array().at(2).as_integer(), 8); @@ -738,11 +738,11 @@ BOOST_AUTO_TEST_CASE(test_value_array) BOOST_CHECK_EQUAL(v1.as_array().at(4).as_integer(), 0); - BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 1); - BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 2); - BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 3); - BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 4); - BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 5); + BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 1); + BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 2); + BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 3); + BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 4); + BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 5); BOOST_CHECK_EQUAL(v2.as_array().at(0).as_integer(), 1); BOOST_CHECK_EQUAL(v2.as_array().at(1).as_integer(), 2); BOOST_CHECK_EQUAL(v2.as_array().at(2).as_integer(), 3); @@ -753,16 +753,16 @@ BOOST_AUTO_TEST_CASE(test_value_array) toml::value v3(v1); BOOST_CHECK(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Array); - BOOST_CHECK(v3.is(toml::value_t::Array)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::array); + BOOST_CHECK(v3.is(toml::value_t::array)); BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_array()); - BOOST_CHECK_EQUAL(v3.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v3.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v3.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v3.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v3.cast().at(4).cast(), 0); + BOOST_CHECK_EQUAL(v3.cast().at(0).cast(), 6); + BOOST_CHECK_EQUAL(v3.cast().at(1).cast(), 7); + BOOST_CHECK_EQUAL(v3.cast().at(2).cast(), 8); + BOOST_CHECK_EQUAL(v3.cast().at(3).cast(), 9); + BOOST_CHECK_EQUAL(v3.cast().at(4).cast(), 0); BOOST_CHECK_EQUAL(v3.as_array().at(0).as_integer(), 6); BOOST_CHECK_EQUAL(v3.as_array().at(1).as_integer(), 7); BOOST_CHECK_EQUAL(v3.as_array().at(2).as_integer(), 8); @@ -771,11 +771,11 @@ BOOST_AUTO_TEST_CASE(test_value_array) v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -783,14 +783,14 @@ BOOST_AUTO_TEST_CASE(test_value_table) { toml::value v1{{"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_EQUAL(v1.type(), toml::value_t::table); + BOOST_CHECK(v1.is(toml::value_t::table)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_table()); - BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 42); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); - BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "qux"); + BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 42); + BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); + BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "qux"); BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_integer(), 42); BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_float(), 3.14); BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "qux"); @@ -798,14 +798,14 @@ BOOST_AUTO_TEST_CASE(test_value_table) v1 = toml::table{{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Table); - BOOST_CHECK(v1.is(toml::value_t::Table)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); + BOOST_CHECK(v1.is(toml::value_t::table)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_table()); - BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); - BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); + BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); + BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); + BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_float(), 2.71); BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_integer(), 54); BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "quux"); @@ -814,25 +814,25 @@ BOOST_AUTO_TEST_CASE(test_value_table) toml::value v3(v1); BOOST_CHECK(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::Table); - BOOST_CHECK(v3.is(toml::value_t::Table)); + BOOST_CHECK_EQUAL(v3.type(), toml::value_t::table); + BOOST_CHECK(v3.is(toml::value_t::table)); BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_table()); - BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); - BOOST_CHECK_EQUAL(v3.cast().at("bar").cast(), 54); - BOOST_CHECK_EQUAL(v3.cast().at("baz").cast().str, "quux"); + BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); + BOOST_CHECK_EQUAL(v3.cast().at("bar").cast(), 54); + BOOST_CHECK_EQUAL(v3.cast().at("baz").cast().str, "quux"); BOOST_CHECK_EQUAL(v3.as_table().at("foo").as_float(), 2.71); BOOST_CHECK_EQUAL(v3.as_table().at("bar").as_integer(), 54); BOOST_CHECK_EQUAL(v3.as_table().at("baz").as_string().str, "quux"); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::Boolean); - BOOST_CHECK(v1.is(toml::value_t::Boolean)); + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); + BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); + BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); } @@ -840,5 +840,5 @@ BOOST_AUTO_TEST_CASE(test_value_empty) { toml::value v1; BOOST_CHECK(v1.is_uninitialized()); - BOOST_CHECK(v1.is(toml::value_t::Empty)); + BOOST_CHECK(v1.is(toml::value_t::empty)); } From 2e34035e7a7b33db42f642edbdb78eac52a888e8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:47:57 +0900 Subject: [PATCH 035/162] feat: :boom: update types and retval of parser - change return value from toml::table to toml::value - enable to change container types and comment policy by template --- toml/parser.hpp | 164 ++++++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 67 deletions(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index a345611..ab29d76 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -869,13 +869,16 @@ parse_key(location& loc) } // forward-decl to implement parse_array and parse_table -template -result parse_value(location&); +template +result parse_value(location&); -template -result>, std::string> +template +result>, std::string> parse_array(location& loc) { + using value_type = Value; + using array_type = typename value_type::array_type; + const auto first = loc.iter(); if(loc.iter() == loc.end()) { @@ -890,7 +893,7 @@ parse_array(location& loc) using lex_ws_comment_newline = repeat< either, unlimited>; - array retval; + array_type retval; while(loc.iter() != loc.end()) { lex_ws_comment_newline::invoke(loc); // skip @@ -902,7 +905,7 @@ parse_array(location& loc) region(loc, first, loc.iter()))); } - if(auto val = parse_value(loc)) + if(auto val = parse_value(loc)) { if(!retval.empty() && retval.front().type() != val.as_ok().type()) { @@ -966,10 +969,12 @@ parse_array(location& loc) {{std::addressof(loc), "should be closed"}})); } -template -result, region>, value>, std::string> +template +result, region>, Value>, std::string> parse_key_value_pair(location& loc) { + using value_type = Value; + const auto first = loc.iter(); auto key_reg = parse_key(loc); if(!key_reg) @@ -1013,7 +1018,7 @@ parse_key_value_pair(location& loc) } const auto after_kvsp = loc.iter(); // err msg - auto val = parse_value(loc); + auto val = parse_value(loc); if(!val) { std::string msg; @@ -1123,9 +1128,9 @@ bool is_valid_forward_table_definition(const value& fwd, return false; } -template +template result -insert_nested_key(table& root, const toml::value& v, +insert_nested_key(typename Value::table_type& root, const Value& v, InputIterator iter, const InputIterator last, region key_reg, const bool is_array_of_table = false) @@ -1133,10 +1138,14 @@ insert_nested_key(table& root, const toml::value& v, static_assert(std::is_same::value_type>::value,""); + using value_type = Value; + using table_type = typename value_type::table_type; + using array_type = typename value_type::array_type; + const auto first = iter; assert(iter != last); - table* tab = std::addressof(root); + table_type* tab = std::addressof(root); for(; iter != last; ++iter) // search recursively { const key& k = *iter; @@ -1176,7 +1185,7 @@ insert_nested_key(table& root, const toml::value& v, })); } // the above if-else-if checks tab->at(k) is an array - array& a = tab->at(k).as_array(); + auto& a = tab->at(k).as_array(); if(!(a.front().is_table())) { throw syntax_error(format_underline(concat_to_string( @@ -1223,7 +1232,7 @@ insert_nested_key(table& root, const toml::value& v, } else // if not, we need to create the array of table { - toml::value aot(toml::array(1, v), key_reg); + value_type aot(array_type(1, v), key_reg); tab->insert(std::make_pair(k, aot)); return ok(true); } @@ -1298,7 +1307,7 @@ insert_nested_key(table& root, const toml::value& v, // [x.y.z] if(tab->count(k) == 0) { - (*tab)[k] = toml::value(toml::table{}, key_reg); + (*tab)[k] = value_type(table_type{}, key_reg); } // type checking... @@ -1308,7 +1317,7 @@ insert_nested_key(table& root, const toml::value& v, } else if(tab->at(k).is_array()) // inserting to array-of-tables? { - array& a = (*tab)[k].as_array(); + auto& a = (*tab)[k].as_array(); if(!a.back().is_table()) { throw syntax_error(format_underline(concat_to_string( @@ -1338,12 +1347,15 @@ insert_nested_key(table& root, const toml::value& v, return err(std::string("toml::detail::insert_nested_key: never reach here")); } -template -result>, std::string> +template +result>, std::string> parse_inline_table(location& loc) { + using value_type = Value; + using table_type = typename value_type::table_type; + const auto first = loc.iter(); - table retval; + table_type retval; if(!(loc.iter() != loc.end() && *loc.iter() == '{')) { return err(format_underline("[error] toml::parse_inline_table: ", @@ -1361,14 +1373,14 @@ parse_inline_table(location& loc) retval, region(loc, first, loc.iter()))); } - const auto kv_r = parse_key_value_pair(loc); + const auto kv_r = parse_key_value_pair(loc); if(!kv_r) { return err(kv_r.unwrap_err()); } const std::vector& keys = kv_r.unwrap().first.first; const region& key_reg = kv_r.unwrap().first.second; - const value& val = kv_r.unwrap().second; + const value_type& val = kv_r.unwrap().second; const auto inserted = insert_nested_key(retval, val, keys.begin(), keys.end(), key_reg); @@ -1414,22 +1426,22 @@ value_t guess_number_type(const location& l) { location loc = l; - if(lex_offset_date_time::invoke(loc)) {return value_t::OffsetDatetime;} + if(lex_offset_date_time::invoke(loc)) {return value_t::offset_datetime;} loc.reset(l.iter()); - if(lex_local_date_time::invoke(loc)) {return value_t::LocalDatetime;} + if(lex_local_date_time::invoke(loc)) {return value_t::local_datetime;} loc.reset(l.iter()); - if(lex_local_date::invoke(loc)) {return value_t::LocalDate;} + if(lex_local_date::invoke(loc)) {return value_t::local_date;} loc.reset(l.iter()); - if(lex_local_time::invoke(loc)) {return value_t::LocalTime;} + if(lex_local_time::invoke(loc)) {return value_t::local_time;} loc.reset(l.iter()); - if(lex_float::invoke(loc)) {return value_t::Float;} + if(lex_float::invoke(loc)) {return value_t::floating;} loc.reset(l.iter()); - return value_t::Integer; + return value_t::integer; } template @@ -1437,21 +1449,23 @@ value_t guess_value_type(const location& loc) { switch(*loc.iter()) { - case '"' : {return value_t::String; } - case '\'': {return value_t::String; } - case 't' : {return value_t::Boolean;} - case 'f' : {return value_t::Boolean;} - case '[' : {return value_t::Array; } - case '{' : {return value_t::Table; } - case 'i' : {return value_t::Float; } // inf. - case 'n' : {return value_t::Float; } // nan. + case '"' : {return value_t::string; } + case '\'': {return value_t::string; } + case 't' : {return value_t::boolean; } + case 'f' : {return value_t::boolean; } + case '[' : {return value_t::array; } + case '{' : {return value_t::table; } + case 'i' : {return value_t::floating;} // inf. + case 'n' : {return value_t::floating;} // nan. default : {return guess_number_type(loc);} } } -template -result parse_value(location& loc) +template +result parse_value(location& loc) { + using value_type = Value; + const auto first = loc.iter(); if(first == loc.end()) { @@ -1461,16 +1475,16 @@ result parse_value(location& loc) switch(guess_value_type(loc)) { - case value_t::Boolean : {return parse_boolean(loc); } - case value_t::Integer : {return parse_integer(loc); } - case value_t::Float : {return parse_floating(loc); } - case value_t::String : {return parse_string(loc); } - case value_t::OffsetDatetime : {return parse_offset_datetime(loc);} - case value_t::LocalDatetime : {return parse_local_datetime(loc); } - case value_t::LocalDate : {return parse_local_date(loc); } - case value_t::LocalTime : {return parse_local_time(loc); } - case value_t::Array : {return parse_array(loc); } - case value_t::Table : {return parse_inline_table(loc); } + case value_t::boolean : {return parse_boolean(loc); } + case value_t::integer : {return parse_integer(loc); } + case value_t::floating : {return parse_floating(loc); } + case value_t::string : {return parse_string(loc); } + case value_t::offset_datetime: {return parse_offset_datetime(loc);} + case value_t::local_datetime : {return parse_local_datetime(loc); } + case value_t::local_date : {return parse_local_date(loc); } + case value_t::local_time : {return parse_local_time(loc); } + case value_t::array : {return parse_array(loc); } + case value_t::table : {return parse_inline_table(loc);} default: { const auto msg = format_underline("[error] toml::parse_value: " @@ -1594,13 +1608,17 @@ parse_array_table_key(location& loc) } // parse table body (key-value pairs until the iter hits the next [tablekey]) -template -result parse_ml_table(location& loc) +template +result +parse_ml_table(location& loc) { + using value_type = Value; + using table_type = typename value_type::table_type; + const auto first = loc.iter(); if(first == loc.end()) { - return ok(toml::table{}); + return ok(table_type{}); } // XXX at lest one newline is needed. @@ -1608,7 +1626,7 @@ result parse_ml_table(location& loc) sequence, maybe, lex_newline>, at_least<1>>; skip_line::invoke(loc); - table tab; + table_type tab; while(loc.iter() != loc.end()) { lex_ws::invoke(loc); @@ -1624,11 +1642,11 @@ result parse_ml_table(location& loc) return ok(tab); } - if(const auto kv = parse_key_value_pair(loc)) + if(const auto kv = parse_key_value_pair(loc)) { - const std::vector& keys = kv.unwrap().first.first; + const std::vector& keys = kv.unwrap().first.first; const region& key_reg = kv.unwrap().first.second; - const value& val = kv.unwrap().second; + const value_type& val = kv.unwrap().second; const auto inserted = insert_nested_key(tab, val, keys.begin(), keys.end(), key_reg); if(!inserted) @@ -1673,18 +1691,21 @@ result parse_ml_table(location& loc) return ok(tab); } -template -result parse_toml_file(location& loc) +template +result parse_toml_file(location& loc) { + using value_type = Value; + using table_type = typename value_type::table_type; + const auto first = loc.iter(); if(first == loc.end()) { - return ok(toml::table{}); + return ok(value_type(table_type{})); } - table data; + table_type data; // root object is also a table, but without [tablename] - if(auto tab = parse_ml_table(loc)) + if(auto tab = parse_ml_table(loc)) { data = std::move(tab.unwrap()); } @@ -1700,14 +1721,14 @@ result parse_toml_file(location& loc) // message. if(const auto tabkey = parse_array_table_key(loc)) { - const auto tab = parse_ml_table(loc); + const auto tab = parse_ml_table(loc); if(!tab){return err(tab.unwrap_err());} const auto& keys = tabkey.unwrap().first; const auto& reg = tabkey.unwrap().second; const auto inserted = insert_nested_key(data, - toml::value(tab.unwrap(), reg), + value_type(tab.unwrap(), reg), keys.begin(), keys.end(), reg, /*is_array_of_table=*/ true); if(!inserted) {return err(inserted.unwrap_err());} @@ -1716,14 +1737,14 @@ result parse_toml_file(location& loc) } if(const auto tabkey = parse_table_key(loc)) { - const auto tab = parse_ml_table(loc); + const auto tab = parse_ml_table(loc); if(!tab){return err(tab.unwrap_err());} const auto& keys = tabkey.unwrap().first; const auto& reg = tabkey.unwrap().second; const auto inserted = insert_nested_key(data, - toml::value(tab.unwrap(), reg), keys.begin(), keys.end(), reg); + value_type(tab.unwrap(), reg), keys.begin(), keys.end(), reg); if(!inserted) {return err(inserted.unwrap_err());} continue; @@ -1736,8 +1757,14 @@ result parse_toml_file(location& loc) } // detail -inline table parse(std::istream& is, std::string fname = "unknown file") +template class Table = std::unordered_map, + template class Array = std::vector> +basic_value +parse(std::istream& is, const std::string& fname = "unknown file") { + using value_type = basic_value; + const auto beg = is.tellg(); is.seekg(0, std::ios::end); const auto end = is.tellg(); @@ -1767,7 +1794,7 @@ inline table parse(std::istream& is, std::string fname = "unknown file") } } - const auto data = detail::parse_toml_file(loc); + const auto data = detail::parse_toml_file(loc); if(!data) { throw syntax_error(data.unwrap_err()); @@ -1775,14 +1802,17 @@ inline table parse(std::istream& is, std::string fname = "unknown file") return data.unwrap(); } -inline table parse(const std::string& fname) +template class Table = std::unordered_map, + template class Array = std::vector> +inline basic_value parse(const std::string& fname) { std::ifstream ifs(fname.c_str(), std::ios_base::binary); if(!ifs.good()) { throw std::runtime_error("toml::parse: file open error -> " + fname); } - return parse(ifs, fname); + return parse(ifs, fname); } } // toml From 89f0ace6ee2f424fcc49235d24eafff055ed25a6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:50:01 +0900 Subject: [PATCH 036/162] fix: initialize comment container correctly --- toml/value.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/value.hpp b/toml/value.hpp index 220915f..864dffd 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -300,7 +300,7 @@ class basic_value } basic_value(basic_value&& v) : type_(v.type()), region_info_(std::move(v.region_info_)), - comments_(std::move(comments_)) + comments_(std::move(v.comments_)) { switch(this->type_) // here this->type_ is already initialized { From 319365f86bb9e1dc1e19c2cd85502c11c7227a49 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:50:27 +0900 Subject: [PATCH 037/162] feat: update types in format_error --- toml/value.hpp | 73 ++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 864dffd..bdb734f 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1185,41 +1185,44 @@ inline bool operator>=(const basic_value& lhs, const basic_value hints = {}) -// { -// return detail::format_underline(err_msg, -// std::vector>{ -// {std::addressof(detail::get_region(v)), comment} -// }, std::move(hints)); -// } -// -// inline std::string format_error(const std::string& err_msg, -// const toml::basic_value& v1, const std::string& comment1, -// const toml::basic_value& v2, const std::string& comment2, -// std::vector hints = {}) -// { -// return detail::format_underline(err_msg, -// std::vector>{ -// {std::addressof(detail::get_region(v1)), comment1}, -// {std::addressof(detail::get_region(v2)), comment2} -// }, std::move(hints)); -// } -// -// inline std::string format_error(const std::string& err_msg, -// const toml::basic_value& v1, const std::string& comment1, -// const toml::basic_value& v2, const std::string& comment2, -// const toml::basic_value& v3, const std::string& comment3, -// std::vector hints = {}) -// { -// return detail::format_underline(err_msg, -// std::vector>{ -// {std::addressof(detail::get_region(v1)), comment1}, -// {std::addressof(detail::get_region(v2)), comment2}, -// {std::addressof(detail::get_region(v3)), comment3} -// }, std::move(hints)); -// } +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const basic_value& v, const std::string& comment, + std::vector hints = {}) +{ + return detail::format_underline(err_msg, + std::vector>{ + {std::addressof(detail::get_region(v)), comment} + }, std::move(hints)); +} + +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const toml::basic_value& v1, const std::string& comment1, + const toml::basic_value& v2, const std::string& comment2, + std::vector hints = {}) +{ + return detail::format_underline(err_msg, + std::vector>{ + {std::addressof(detail::get_region(v1)), comment1}, + {std::addressof(detail::get_region(v2)), comment2} + }, std::move(hints)); +} + +template class T, template class A> +inline std::string format_error(const std::string& err_msg, + const toml::basic_value& v1, const std::string& comment1, + const toml::basic_value& v2, const std::string& comment2, + const toml::basic_value& v3, const std::string& comment3, + std::vector hints = {}) +{ + return detail::format_underline(err_msg, + std::vector>{ + {std::addressof(detail::get_region(v1)), comment1}, + {std::addressof(detail::get_region(v2)), comment2}, + {std::addressof(detail::get_region(v3)), comment3} + }, std::move(hints)); +} template class T, template class A> From 5fe166e37545f5ec5be8e5117a1efc9e5259a6a7 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 21:51:37 +0900 Subject: [PATCH 038/162] fix: update value_t::* names in serializer Although currently serializer does not support basic_value, it compiles. --- toml/serializer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 299d019..bd6d668 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -174,7 +174,7 @@ struct serializer for(const auto& item : v) { const auto t = - this->make_inline_table(item.cast()); + this->make_inline_table(item.cast()); if(t.size() + 1 > width_ || // +1 for the last comma {...}, std::find(t.cbegin(), t.cend(), '\n') != t.cend()) @@ -199,7 +199,7 @@ struct serializer token += "[["; token += this->serialize_dotted_key(keys_); token += "]]\n"; - token += this->make_multiline_table(item.cast()); + token += this->make_multiline_table(item.cast()); } return token; } From c313e1382cd64d9bbff43f91602930521fa084f6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 22:00:56 +0900 Subject: [PATCH 039/162] test: update test for multiple translation units --- tests/test_multiple_translation_unit_1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_multiple_translation_unit_1.cpp b/tests/test_multiple_translation_unit_1.cpp index daff11a..08a4f98 100644 --- a/tests/test_multiple_translation_unit_1.cpp +++ b/tests/test_multiple_translation_unit_1.cpp @@ -7,5 +7,5 @@ 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(data); + return read_a(toml::get(data)); } From fe8a909213b43452789535b341af1058424d22c5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 22:09:26 +0900 Subject: [PATCH 040/162] fix: correctly put references --- toml/get.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index c2327a4..42ba7ba 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -34,7 +34,7 @@ template>::value, T> && get(basic_value&& v) { - return v.template cast>::value>(); + return std::move(v).template cast>::value>(); } // ============================================================================ @@ -532,7 +532,7 @@ template(std::declval&>())) find(basic_value& v, const key& ky) { - const auto& tab = v.template cast(); + auto& tab = v.template cast(); if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( From 296ba060ef1d3473d8a50e7b9b84a070c31a9a22 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 22:11:37 +0900 Subject: [PATCH 041/162] test: update typename from CamelCase to snake_case --- tests/test_value.cpp | 142 +++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/tests/test_value.cpp b/tests/test_value.cpp index f90045f..65b77b0 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -23,8 +23,8 @@ BOOST_AUTO_TEST_CASE(test_value_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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); @@ -40,8 +40,8 @@ BOOST_AUTO_TEST_CASE(test_value_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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); @@ -59,8 +59,8 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) BOOST_CHECK_EQUAL(v4.type(), toml::value_t::boolean); BOOST_CHECK(v3.is(toml::value_t::boolean)); BOOST_CHECK(v4.is(toml::value_t::boolean)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); + BOOST_CHECK(v3.is()); + BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_boolean()); BOOST_CHECK(v4.is_boolean()); @@ -76,8 +76,8 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) BOOST_CHECK_EQUAL(v6.type(), toml::value_t::boolean); BOOST_CHECK(v5.is(toml::value_t::boolean)); BOOST_CHECK(v6.is(toml::value_t::boolean)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); + BOOST_CHECK(v5.is()); + BOOST_CHECK(v6.is()); BOOST_CHECK(v3.is_boolean()); BOOST_CHECK(v4.is_boolean()); @@ -93,8 +93,8 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); BOOST_CHECK(v1.is(toml::value_t::integer)); BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_float()); @@ -113,8 +113,8 @@ BOOST_AUTO_TEST_CASE(test_value_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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_integer()); @@ -130,8 +130,8 @@ BOOST_AUTO_TEST_CASE(test_value_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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); BOOST_CHECK(v2.is_integer()); @@ -149,8 +149,8 @@ BOOST_AUTO_TEST_CASE(test_value_integer) BOOST_CHECK_EQUAL(v4.type(), toml::value_t::integer); BOOST_CHECK(v3.is(toml::value_t::integer)); BOOST_CHECK(v4.is(toml::value_t::integer)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); + BOOST_CHECK(v3.is()); + BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_integer()); BOOST_CHECK(v4.is_integer()); @@ -166,8 +166,8 @@ BOOST_AUTO_TEST_CASE(test_value_integer) BOOST_CHECK_EQUAL(v6.type(), toml::value_t::integer); BOOST_CHECK(v5.is(toml::value_t::integer)); BOOST_CHECK(v6.is(toml::value_t::integer)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); + BOOST_CHECK(v5.is()); + BOOST_CHECK(v6.is()); BOOST_CHECK(v5.is_integer()); BOOST_CHECK(v6.is_integer()); @@ -183,8 +183,8 @@ BOOST_AUTO_TEST_CASE(test_value_integer) 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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); @@ -203,8 +203,8 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); BOOST_CHECK(v1.is(toml::value_t::floating)); BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_float()); BOOST_CHECK(v2.is_float()); @@ -220,8 +220,8 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); BOOST_CHECK(v1.is(toml::value_t::floating)); BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_float()); BOOST_CHECK(v2.is_float()); @@ -239,8 +239,8 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK_EQUAL(v4.type(), toml::value_t::floating); BOOST_CHECK(v3.is(toml::value_t::floating)); BOOST_CHECK(v4.is(toml::value_t::floating)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); + BOOST_CHECK(v3.is()); + BOOST_CHECK(v4.is()); BOOST_CHECK(v3.is_float()); BOOST_CHECK(v4.is_float()); @@ -256,8 +256,8 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK_EQUAL(v6.type(), toml::value_t::floating); BOOST_CHECK(v5.is(toml::value_t::floating)); BOOST_CHECK(v6.is(toml::value_t::floating)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); + BOOST_CHECK(v5.is()); + BOOST_CHECK(v6.is()); BOOST_CHECK(v5.is_float()); BOOST_CHECK(v6.is_float()); @@ -273,8 +273,8 @@ BOOST_AUTO_TEST_CASE(test_value_float) 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()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); @@ -296,9 +296,9 @@ BOOST_AUTO_TEST_CASE(test_value_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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v3.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); + BOOST_CHECK(v3.is()); BOOST_CHECK(v1.is_string()); BOOST_CHECK(v2.is_string()); BOOST_CHECK(v3.is_string()); @@ -346,9 +346,9 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v4.is(toml::value_t::string)); BOOST_CHECK(v5.is(toml::value_t::string)); BOOST_CHECK(v6.is(toml::value_t::string)); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); + BOOST_CHECK(v4.is()); + BOOST_CHECK(v5.is()); + BOOST_CHECK(v6.is()); BOOST_CHECK(v4.is_string()); BOOST_CHECK(v5.is_string()); BOOST_CHECK(v6.is_string()); @@ -371,9 +371,9 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v4.is(toml::value_t::string)); BOOST_CHECK(v5.is(toml::value_t::string)); BOOST_CHECK(v6.is(toml::value_t::string)); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); + BOOST_CHECK(v4.is()); + BOOST_CHECK(v5.is()); + BOOST_CHECK(v6.is()); BOOST_CHECK(v4.is_string()); BOOST_CHECK(v5.is_string()); BOOST_CHECK(v6.is_string()); @@ -392,9 +392,9 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK(v1.is(toml::value_t::boolean)); BOOST_CHECK(v2.is(toml::value_t::boolean)); BOOST_CHECK(v3.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v3.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); + BOOST_CHECK(v3.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK(v2.is_boolean()); BOOST_CHECK(v3.is_boolean()); @@ -416,8 +416,8 @@ BOOST_AUTO_TEST_CASE(test_value_string) BOOST_CHECK_EQUAL(v8.type(), toml::value_t::string); BOOST_CHECK(v7.is(toml::value_t::string)); BOOST_CHECK(v8.is(toml::value_t::string)); - BOOST_CHECK(v7.is()); - BOOST_CHECK(v8.is()); + BOOST_CHECK(v7.is()); + BOOST_CHECK(v8.is()); BOOST_CHECK(v7.is_string()); BOOST_CHECK(v8.is_string()); @@ -432,7 +432,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_date); BOOST_CHECK(v1.is(toml::value_t::local_date)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_date()); BOOST_CHECK_EQUAL(v1.cast(), @@ -444,7 +444,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_date); BOOST_CHECK(v1.is(toml::value_t::local_date)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_date()); BOOST_CHECK_EQUAL(v1.cast(), @@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_date); BOOST_CHECK(v2.is(toml::value_t::local_date)); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_local_date()); BOOST_CHECK_EQUAL(v2.cast(), @@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); @@ -484,8 +484,8 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_time); BOOST_CHECK(v1.is(toml::value_t::local_time)); BOOST_CHECK(v2.is(toml::value_t::local_time)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_local_time()); BOOST_CHECK(v2.is_local_time()); @@ -508,7 +508,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_time); BOOST_CHECK(v1.is(toml::value_t::local_time)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_time()); BOOST_CHECK_EQUAL(v1.cast(), toml::local_time(1, 30, 0, 100, 0)); @@ -520,7 +520,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) BOOST_CHECK_EQUAL(v3.type(), toml::value_t::local_time); BOOST_CHECK(v3.is(toml::value_t::local_time)); - BOOST_CHECK(v3.is()); + BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_local_time()); BOOST_CHECK_EQUAL(v3.cast(), @@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); @@ -546,7 +546,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_datetime); BOOST_CHECK(v1.is(toml::value_t::local_datetime)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_datetime()); BOOST_CHECK_EQUAL(v1.cast(), @@ -564,7 +564,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_datetime); BOOST_CHECK(v1.is(toml::value_t::local_datetime)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_local_datetime()); BOOST_CHECK_EQUAL(v1.cast(), @@ -581,7 +581,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_datetime); BOOST_CHECK(v2.is(toml::value_t::local_datetime)); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_local_datetime()); BOOST_CHECK_EQUAL(v2.cast(), @@ -597,7 +597,7 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); @@ -613,7 +613,7 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_offset_datetime()); BOOST_CHECK_EQUAL(v1.cast(), @@ -636,7 +636,7 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_offset_datetime()); BOOST_CHECK_EQUAL(v1.cast(), @@ -656,7 +656,7 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) BOOST_CHECK_EQUAL(v2.type(), toml::value_t::offset_datetime); BOOST_CHECK(v2.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_offset_datetime()); BOOST_CHECK_EQUAL(v2.cast(), @@ -673,7 +673,7 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); @@ -687,12 +687,12 @@ BOOST_AUTO_TEST_CASE(test_value_array) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::array); BOOST_CHECK(v1.is(toml::value_t::array)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_array()); BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); BOOST_CHECK(v2.is(toml::value_t::array)); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_array()); BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 1); @@ -718,12 +718,12 @@ BOOST_AUTO_TEST_CASE(test_value_array) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::array); BOOST_CHECK(v1.is(toml::value_t::array)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_array()); BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); BOOST_CHECK(v2.is(toml::value_t::array)); - BOOST_CHECK(v2.is()); + BOOST_CHECK(v2.is()); BOOST_CHECK(v2.is_array()); BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 6); @@ -755,7 +755,7 @@ BOOST_AUTO_TEST_CASE(test_value_array) BOOST_CHECK_EQUAL(v3.type(), toml::value_t::array); BOOST_CHECK(v3.is(toml::value_t::array)); - BOOST_CHECK(v3.is()); + BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_array()); BOOST_CHECK_EQUAL(v3.cast().at(0).cast(), 6); @@ -773,7 +773,7 @@ BOOST_AUTO_TEST_CASE(test_value_array) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); @@ -785,7 +785,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); BOOST_CHECK(v1.is(toml::value_t::table)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_table()); BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 42); @@ -800,7 +800,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); BOOST_CHECK(v1.is(toml::value_t::table)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_table()); BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); @@ -816,7 +816,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v3.type(), toml::value_t::table); BOOST_CHECK(v3.is(toml::value_t::table)); - BOOST_CHECK(v3.is()); + BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_table()); BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); @@ -830,7 +830,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) v1 = true; BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is()); BOOST_CHECK(v1.is_boolean()); BOOST_CHECK_EQUAL(v1.cast(), true); BOOST_CHECK_EQUAL(v1.as_boolean(), true); From ad3c1950f227d2c2b3de7ec062a48d777e8f5337 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 22:12:32 +0900 Subject: [PATCH 042/162] test: use find instead of get(v.at("")) --- tests/test_serialize_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 0f6e546..816dbbe 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(test_example) auto serialized = toml::parse("tmp1.toml"); { - auto& owner = toml::get(serialized.at("owner")); + auto& owner = toml::find(serialized, "owner"); auto& bio = toml::get(owner.at("bio")); const auto CR = std::find(bio.begin(), bio.end(), '\r'); if(CR != bio.end()) From cf1114b47b0126654fbd2e7e9b85a7e862fd0a8f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 2 Jun 2019 22:13:36 +0900 Subject: [PATCH 043/162] test: update typenames from Camel to snake --- tests/test_parse_unicode.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_parse_unicode.cpp b/tests/test_parse_unicode.cpp index 21f5d32..30d909a 100644 --- a/tests/test_parse_unicode.cpp +++ b/tests/test_parse_unicode.cpp @@ -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 the = toml::get(data.at("the")); + const auto the = toml::find(data, "the"); BOOST_CHECK_EQUAL(toml::get(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")); - const auto hard = toml::get(the.at("hard")); + const auto hard = toml::get(the.at("hard")); const std::vector expected_the_hard_test_array{"] ", " # "}; BOOST_CHECK(toml::get>(hard.at("test_array")) == expected_the_hard_test_array); @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) BOOST_CHECK_EQUAL(toml::get(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")); // - const auto bit = toml::get(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23"))); + const auto bit = toml::get(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23"))); BOOST_CHECK_EQUAL(toml::get(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")); const std::vector expected_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 the = toml::get(data.at("the")); + const auto the = toml::find(data, "the"); BOOST_CHECK_EQUAL(toml::get(the.at("test_string")), std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #")); - const auto hard = toml::get(the.at("hard")); + const auto hard = toml::get(the.at("hard")); const std::vector expected_the_hard_test_array{"] ", " # "}; BOOST_CHECK(toml::get>(hard.at("test_array")) == expected_the_hard_test_array); @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) BOOST_CHECK_EQUAL(toml::get(hard.at("harder_test_string")), std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")); - const auto bit = toml::get(hard.at(std::string(u8"βïƭ#"))); + const auto bit = toml::get(hard.at(std::string(u8"βïƭ#"))); BOOST_CHECK_EQUAL(toml::get(bit.at(std::string(u8"ωλáƭ?"))), std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?")); const std::vector expected_multi_line_array{"]"}; From f19b3822bba583f5ceff6c6c3b0d484cd8c80b62 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 21:43:35 +0900 Subject: [PATCH 044/162] feat: :boom: change as_float -> as_floating --- toml/value.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index bdb734f..eaad392 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -946,7 +946,7 @@ class basic_value boolean const& as_boolean() const& noexcept {return this->boolean_;} integer const& as_integer() const& noexcept {return this->integer_;} - floating const& as_float() const& noexcept {return this->floating_;} + floating const& as_floating() const& noexcept {return this->floating_;} string const& as_string() const& noexcept {return this->string_;} offset_datetime const& as_offset_datetime() const& noexcept {return this->offset_datetime_;} local_datetime const& as_local_datetime() const& noexcept {return this->local_datetime_;} @@ -957,7 +957,7 @@ class basic_value boolean & as_boolean() & noexcept {return this->boolean_;} integer & as_integer() & noexcept {return this->integer_;} - floating & as_float() & noexcept {return this->floating_;} + floating & as_floating() & noexcept {return this->floating_;} string & as_string() & noexcept {return this->string_;} offset_datetime& as_offset_datetime() & noexcept {return this->offset_datetime_;} local_datetime & as_local_datetime() & noexcept {return this->local_datetime_;} @@ -968,7 +968,7 @@ class basic_value boolean && as_boolean() && noexcept {return std::move(this->boolean_);} integer && as_integer() && noexcept {return std::move(this->integer_);} - floating && as_float() && noexcept {return std::move(this->floating_);} + floating && as_floating() && noexcept {return std::move(this->floating_);} string && as_string() && noexcept {return std::move(this->string_);} offset_datetime&& as_offset_datetime() && noexcept {return std::move(this->offset_datetime_);} local_datetime && as_local_datetime() && noexcept {return std::move(this->local_datetime_);} From ae2bafa90709142025a5520eebd2c8eba2266da2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 21:44:11 +0900 Subject: [PATCH 045/162] fix: correct SFINAE conditions and types --- toml/get.hpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 42ba7ba..0ca5435 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -635,9 +635,7 @@ get_or(const basic_value& v, T&& opt) } template class M, template class V> -detail::enable_if_t::type>::type, - std::string>::value, std::string>& +detail::enable_if_t::value, std::string>& get_or(basic_value& v, T& opt) { try @@ -662,7 +660,7 @@ get_or(basic_value&& v, T&& opt) } catch(...) { - return opt; + return std::string(opt); } } @@ -673,7 +671,7 @@ template class M, template class V> detail::enable_if_t::type>::value, std::string> -get_or(basic_value&& v, T&& opt) +get_or(const basic_value& v, T&& opt) { try { @@ -692,9 +690,10 @@ template class M, template class V> detail::enable_if_t>>, - detail::negation>, + detail::negation::type>::type>>, detail::negation::type>> - >::value, T> + >::value, typename std::remove_reference::type> get_or(const basic_value& v, T&& opt) { try @@ -704,7 +703,7 @@ get_or(const basic_value& v, T&& opt) } catch(...) { - return opt; + return std::forward(opt); } } From 761718b3b9666a7200aec76216520630b33ccb19 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 21:44:47 +0900 Subject: [PATCH 046/162] test: update retval of parse and related get/find --- tests/test_parse_file.cpp | 244 +++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 123 deletions(-) diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index b5c6a8a..0e974b7 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -14,42 +14,42 @@ BOOST_AUTO_TEST_CASE(test_example) { const auto data = toml::parse("toml/tests/example.toml"); - BOOST_CHECK_EQUAL(toml::get(data.at("title")), "TOML Example"); - toml::Table owner = toml::get(data.at("owner")); + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::get(owner.at("name")), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::get(owner.at("organization")), "GitHub"); - BOOST_CHECK_EQUAL(toml::get(owner.at("bio")), + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::get(owner.at("dob")), + BOOST_CHECK_EQUAL(toml::find(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))); } - toml::Table database = toml::get(data.at("database")); + const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::get(database.at("server")), "192.168.1.1"); + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::get>(database.at("ports")) == expected_ports); - BOOST_CHECK_EQUAL(toml::get(database.at("connection_max")), 5000); - BOOST_CHECK_EQUAL(toml::get(database.at("enabled")), true); + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); } - toml::Table servers = toml::get(data.at("servers")); + const auto& servers = toml::find(data, "servers"); { - toml::Table alpha = toml::get(servers.at("alpha")); + toml::table alpha = toml::find(servers, "alpha"); BOOST_CHECK_EQUAL(toml::get(alpha.at("ip")), "10.0.0.1"); BOOST_CHECK_EQUAL(toml::get(alpha.at("dc")), "eqdc10"); - toml::Table beta = toml::get(servers.at("beta")); + toml::table beta = toml::find(servers, "beta"); BOOST_CHECK_EQUAL(toml::get(beta.at("ip")), "10.0.0.2"); BOOST_CHECK_EQUAL(toml::get(beta.at("dc")), "eqdc10"); BOOST_CHECK_EQUAL(toml::get(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD"); } - toml::Table clients = toml::get(data.at("clients")); + const auto& clients = toml::find(data, "clients"); { - toml::Array clients_data = toml::get(clients.at("data")); + toml::array clients_data = toml::find(clients, "data"); std::vector expected_name{"gamma", "delta"}; BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); @@ -57,12 +57,12 @@ BOOST_AUTO_TEST_CASE(test_example) BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::get>(clients.at("hosts")) == + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); } - std::vector products = - toml::get>(data.at("products")); + std::vector products = + toml::find>(data, "products"); { BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), "Hammer"); @@ -83,42 +83,42 @@ BOOST_AUTO_TEST_CASE(test_example_stream) std::ifstream ifs("toml/tests/example.toml"); const auto data = toml::parse(ifs); - BOOST_CHECK_EQUAL(toml::get(data.at("title")), "TOML Example"); - toml::Table owner = toml::get(data.at("owner")); + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::get(owner.at("name")), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::get(owner.at("organization")), "GitHub"); - BOOST_CHECK_EQUAL(toml::get(owner.at("bio")), + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::get(owner.at("dob")), + BOOST_CHECK_EQUAL(toml::find(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))); } - toml::Table database = toml::get(data.at("database")); + const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::get(database.at("server")), "192.168.1.1"); + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::get>(database.at("ports")) == expected_ports); - BOOST_CHECK_EQUAL(toml::get(database.at("connection_max")), 5000); - BOOST_CHECK_EQUAL(toml::get(database.at("enabled")), true); + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); } - toml::Table servers = toml::get(data.at("servers")); + const auto& servers = toml::find(data, "servers"); { - toml::Table alpha = toml::get(servers.at("alpha")); + toml::table alpha = toml::find(servers, "alpha"); BOOST_CHECK_EQUAL(toml::get(alpha.at("ip")), "10.0.0.1"); BOOST_CHECK_EQUAL(toml::get(alpha.at("dc")), "eqdc10"); - toml::Table beta = toml::get(servers.at("beta")); + toml::table beta = toml::find(servers, "beta"); BOOST_CHECK_EQUAL(toml::get(beta.at("ip")), "10.0.0.2"); BOOST_CHECK_EQUAL(toml::get(beta.at("dc")), "eqdc10"); BOOST_CHECK_EQUAL(toml::get(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD"); } - toml::Table clients = toml::get(data.at("clients")); + const auto& clients = toml::find(data, "clients"); { - toml::Array clients_data = toml::get(clients.at("data")); + toml::array clients_data = toml::find(clients, "data"); std::vector expected_name{"gamma", "delta"}; BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); @@ -126,12 +126,12 @@ BOOST_AUTO_TEST_CASE(test_example_stream) BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::get>(clients.at("hosts")) == + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); } - std::vector products = - toml::get>(data.at("products")); + std::vector products = + toml::find>(data, "products"); { BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), "Hammer"); @@ -147,51 +147,49 @@ BOOST_AUTO_TEST_CASE(test_example_stream) } } - BOOST_AUTO_TEST_CASE(test_fruit) { const auto data = toml::parse("toml/tests/fruit.toml"); - const auto blah = toml::get>( - toml::get(data.at("fruit")).at("blah")); - BOOST_CHECK_EQUAL(toml::get(blah.at(0).at("name")), "apple"); - BOOST_CHECK_EQUAL(toml::get(blah.at(1).at("name")), "banana"); + const auto blah = toml::find(toml::find(data, "fruit"), "blah"); + BOOST_CHECK_EQUAL(toml::find(blah.at(0), "name"), "apple"); + BOOST_CHECK_EQUAL(toml::find(blah.at(1), "name"), "banana"); { - const auto physical = toml::get(blah.at(0).at("physical")); - BOOST_CHECK_EQUAL(toml::get(physical.at("color")), "red"); - BOOST_CHECK_EQUAL(toml::get(physical.at("shape")), "round"); + const auto physical = toml::find(blah.at(0), "physical"); + BOOST_CHECK_EQUAL(toml::find(physical, "color"), "red"); + BOOST_CHECK_EQUAL(toml::find(physical, "shape"), "round"); } { - const auto physical = toml::get(blah.at(1).at("physical")); - BOOST_CHECK_EQUAL(toml::get(physical.at("color")), "yellow"); - BOOST_CHECK_EQUAL(toml::get(physical.at("shape")), "bent"); + const auto physical = toml::find(blah.at(1), "physical"); + BOOST_CHECK_EQUAL(toml::find(physical, "color"), "yellow"); + BOOST_CHECK_EQUAL(toml::find(physical, "shape"), "bent"); } } BOOST_AUTO_TEST_CASE(test_hard_example) { const auto data = toml::parse("toml/tests/hard_example.toml"); - const auto the = toml::get(data.at("the")); - BOOST_CHECK_EQUAL(toml::get(the.at("test_string")), + const auto the = toml::find(data, "the"); + BOOST_CHECK_EQUAL(toml::find(the, "test_string"), "You'll hate me after this - #"); - const auto hard = toml::get(the.at("hard")); + const auto hard = toml::find(the, "hard"); const std::vector expected_the_hard_test_array{"] ", " # "}; - BOOST_CHECK(toml::get>(hard.at("test_array")) == + BOOST_CHECK(toml::find>(hard, "test_array") == expected_the_hard_test_array); const std::vector expected_the_hard_test_array2{ "Test #11 ]proved that", "Experiment #9 was a success"}; - BOOST_CHECK(toml::get>(hard.at("test_array2")) == + BOOST_CHECK(toml::find>(hard, "test_array2") == expected_the_hard_test_array2); - BOOST_CHECK_EQUAL(toml::get(hard.at("another_test_string")), + BOOST_CHECK_EQUAL(toml::find(hard, "another_test_string"), " Same thing, but with a string #"); - BOOST_CHECK_EQUAL(toml::get(hard.at("harder_test_string")), + BOOST_CHECK_EQUAL(toml::find(hard, "harder_test_string"), " And when \"'s are in the string, along with # \""); - const auto bit = toml::get(hard.at("bit#")); - BOOST_CHECK_EQUAL(toml::get(bit.at("what?")), + const auto bit = toml::find(hard, "bit#"); + BOOST_CHECK_EQUAL(toml::find(bit, "what?"), "You don't think some user won't do that?"); const std::vector expected_multi_line_array{"]"}; - BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == + BOOST_CHECK(toml::find>(bit, "multi_line_array") == expected_multi_line_array); } @@ -210,8 +208,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) std::istringstream iss(table); const auto data = toml::parse(iss, "test_file_with_BOM.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -226,8 +224,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) } const auto data = toml::parse("tmp.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -239,8 +237,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) std::istringstream iss(table); const auto data = toml::parse(iss, "test_file_with_BOM_CRLF.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -258,8 +256,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) } const auto data = toml::parse("tmp.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } } @@ -275,8 +273,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -288,8 +286,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_CRLF.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { @@ -302,8 +300,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -315,8 +313,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { @@ -329,8 +327,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_ws.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -342,8 +340,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_ws.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } } @@ -362,8 +360,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -377,8 +375,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } // comment w/ newline @@ -394,8 +392,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -409,8 +407,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } // CRLF version @@ -426,8 +424,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -441,8 +439,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -455,8 +453,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -470,8 +468,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } } @@ -489,8 +487,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -504,8 +502,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } // with whitespaces @@ -521,8 +519,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -536,8 +534,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -551,8 +549,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -566,8 +564,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } // with whitespaces but no newline @@ -582,8 +580,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } @@ -600,8 +598,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -615,8 +613,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } // with whitespaces @@ -632,8 +630,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -647,8 +645,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -662,8 +660,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -677,8 +675,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } { const std::string table( @@ -691,7 +689,7 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::get (data.at("key")), "value"); - BOOST_CHECK_EQUAL(toml::find(data.at("table"), "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); + BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } } From d7c5606dcff7b6a113d8bbfaf335900fd1924cb9 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 21:46:48 +0900 Subject: [PATCH 047/162] fix: update as_float -> floating --- toml/value.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index eaad392..e8f5805 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1078,7 +1078,7 @@ operator==(const basic_value& lhs, const basic_value& rhs) } case value_t::floating : { - return lhs.as_float() == rhs.as_float(); + return lhs.as_floating() == rhs.as_floating(); } case value_t::string : { @@ -1129,7 +1129,7 @@ operator<(const basic_value& lhs, const basic_value& rhs) } case value_t::floating : { - return lhs.as_float() < rhs.as_float(); + return lhs.as_floating() < rhs.as_floating(); } case value_t::string : { @@ -1233,7 +1233,7 @@ visit(Visitor&& visitor, const toml::basic_value& v) { case value_t::boolean : {return visitor(v.as_boolean ());} case value_t::integer : {return visitor(v.as_integer ());} - case value_t::floating : {return visitor(v.as_float ());} + case value_t::floating : {return visitor(v.as_floating ());} case value_t::string : {return visitor(v.as_string ());} case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} case value_t::local_datetime : {return visitor(v.as_local_datetime ());} @@ -1257,7 +1257,7 @@ visit(Visitor&& visitor, toml::basic_value& v) { case value_t::boolean : {return visitor(v.as_boolean ());} case value_t::integer : {return visitor(v.as_integer ());} - case value_t::floating : {return visitor(v.as_float ());} + case value_t::floating : {return visitor(v.as_floating ());} case value_t::string : {return visitor(v.as_string ());} case value_t::offset_datetime: {return visitor(v.as_offset_datetime());} case value_t::local_datetime : {return visitor(v.as_local_datetime ());} @@ -1281,7 +1281,7 @@ visit(Visitor&& visitor, toml::basic_value&& v) { case value_t::boolean : {return visitor(std::move(v.as_boolean ()));} case value_t::integer : {return visitor(std::move(v.as_integer ()));} - case value_t::floating : {return visitor(std::move(v.as_float ()));} + case value_t::floating : {return visitor(std::move(v.as_floating ()));} case value_t::string : {return visitor(std::move(v.as_string ()));} case value_t::offset_datetime: {return visitor(std::move(v.as_offset_datetime()));} case value_t::local_datetime : {return visitor(std::move(v.as_local_datetime ()));} From 53efaed1798d19ca8bc222c05873de6d9c6c4f71 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 22:01:16 +0900 Subject: [PATCH 048/162] test: update interfaces of parse_* and value --- tests/test_literals.cpp | 4 +- tests/test_parse_array.cpp | 42 +++++++++---------- tests/test_parse_boolean.cpp | 4 +- tests/test_parse_datetime.cpp | 40 +++++++++--------- tests/test_parse_floating.cpp | 70 +++++++++++++++---------------- tests/test_parse_inline_table.cpp | 12 +++--- tests/test_parse_integer.cpp | 48 ++++++++++----------- tests/test_parse_string.cpp | 36 ++++++++-------- tests/test_parse_table.cpp | 4 +- tests/test_value.cpp | 42 +++++++++---------- 10 files changed, 151 insertions(+), 151 deletions(-) diff --git a/tests/test_literals.cpp b/tests/test_literals.cpp index 2342a44..3323168 100644 --- a/tests/test_literals.cpp +++ b/tests/test_literals.cpp @@ -78,8 +78,8 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal) const toml::value v1 = u8"3.1415"_toml; const toml::value v2 = u8"6.02e+23"_toml; - BOOST_CHECK(v1.is_float()); - BOOST_CHECK(v2.is_float()); + BOOST_CHECK(v1.is_floating()); + BOOST_CHECK(v2.is_floating()); BOOST_CHECK_CLOSE(toml::get(v1), 3.1415, 0.00001); BOOST_CHECK_CLOSE(toml::get(v2), 6.02e23, 0.0001); } diff --git a/tests/test_parse_array.cpp b/tests/test_parse_array.cpp index 6350c3a..9cfbc4d 100644 --- a/tests/test_parse_array.cpp +++ b/tests/test_parse_array.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE "parse_array_test" +#define BOOST_TEST_MODULE "parse_array_test" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST #include #else @@ -13,118 +13,118 @@ using namespace detail; BOOST_AUTO_TEST_CASE(test_oneline_array) { - TOML11_TEST_PARSE_EQUAL(parse_array, "[]", array()); + TOML11_TEST_PARSE_EQUAL(parse_array, "[]", array()); { array a(5); 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); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5]", a); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\"]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\"]", a); } { array a(5); 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); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5,]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[3,1,4,1,5,]", a); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\",]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\", \"bar\", \"baz\",]", a); } } 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(array())); { array a(5); 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); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5]", toml::value(a)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5]", toml::value(a)); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); 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, "[\"foo\", \"bar\", \"baz\"]", toml::value(a)); } { array a(5); 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); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5,]", toml::value(a)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,1,4,1,5,]", toml::value(a)); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); 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, "[\"foo\", \"bar\", \"baz\",]", toml::value(a)); } } BOOST_AUTO_TEST_CASE(test_multiline_array) { - TOML11_TEST_PARSE_EQUAL(parse_array, "[\n#comment\n]", array()); + TOML11_TEST_PARSE_EQUAL(parse_array, "[\n#comment\n]", array()); { array a(5); 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); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,\n1,\n4,\n1,\n5]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[3,\n1,\n4,\n1,\n5]", a); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); a[2] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",\n\"bar\",\n\"baz\"]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[\"foo\",\n\"bar\",\n\"baz\"]", a); } { array a(5); 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); - TOML11_TEST_PARSE_EQUAL(parse_array, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", a); + TOML11_TEST_PARSE_EQUAL(parse_array, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", a); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("b#r"); 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, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", a); } } 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, "[\n#comment\n]", toml::value(array())); { array a(5); 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); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,\n1,\n4,\n1,\n5]", toml::value(a)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "[3,\n1,\n4,\n1,\n5]", toml::value(a)); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("bar"); 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, "[\"foo\",\n\"bar\",\n\"baz\"]", toml::value(a)); } { array a(5); 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); - 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, "[3,#comment\n1,#comment\n4,#comment\n1,#comment\n5]", toml::value(a)); } { array a(3); a[0] = toml::value("foo"); a[1] = toml::value("b#r"); 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, "[\"foo\",#comment\n\"b#r\",#comment\n\"b#z\"#comment\n]", toml::value(a)); } } diff --git a/tests/test_parse_boolean.cpp b/tests/test_parse_boolean.cpp index 5224a93..068aaa4 100644 --- a/tests/test_parse_boolean.cpp +++ b/tests/test_parse_boolean.cpp @@ -19,6 +19,6 @@ BOOST_AUTO_TEST_CASE(test_boolean) 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, "false", toml::value(false)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "true", toml::value( true)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "false", toml::value(false)); } diff --git a/tests/test_parse_datetime.cpp b/tests/test_parse_datetime.cpp index 7a4e2e7..832aa06 100644 --- a/tests/test_parse_datetime.cpp +++ b/tests/test_parse_datetime.cpp @@ -21,10 +21,10 @@ BOOST_AUTO_TEST_CASE(test_time) 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, "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, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999))); + 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, "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, "07:32:00.999999", toml::value(toml::local_time(7, 32, 0, 999, 999))); } BOOST_AUTO_TEST_CASE(test_date) @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(test_date) } BOOST_AUTO_TEST_CASE(test_date_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-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) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.99", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27t07:32:00.999999", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.99", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27 07:32:00.999999", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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)))); } @@ -111,23 +111,23 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime) 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, "1979-05-27T07:32:00Z", 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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99Z", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99Z", 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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999Z", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999Z", 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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00+09:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00+09:00", 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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99+09:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.99+09:00", 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)))); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999+09:00", + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1979-05-27T07:32:00.999999+09:00", 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)))); } diff --git a/tests/test_parse_floating.cpp b/tests/test_parse_floating.cpp index e98dbe7..c7dcc16 100644 --- a/tests/test_parse_floating.cpp +++ b/tests/test_parse_floating.cpp @@ -32,20 +32,20 @@ BOOST_AUTO_TEST_CASE(test_fractional) 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, "0.1", value( 0.1)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "+3.14", value( 3.14)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "+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, "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, "-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, "-0.0", value(-0.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "0.001", value( 0.001)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "-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, "+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, "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, "-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, "-0.0", value(-0.0)); } BOOST_AUTO_TEST_CASE(test_exponential) @@ -72,24 +72,24 @@ BOOST_AUTO_TEST_CASE(test_exponential) BOOST_AUTO_TEST_CASE(test_exponential_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e-10", value(1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e-10", value(1e-10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e10", value(-1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e+10", value(-1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "1E10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E+10", value(1e10)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "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, "+0e0", value( 0.0)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0e0", value(-0.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1e-10", value(1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1e-10", value(1e-10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e10", value(-1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1e+10", value(-1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "1E10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1E+10", value(1e10)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "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, "+0e0", value( 0.0)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-0e0", value(-0.0)); } BOOST_AUTO_TEST_CASE(test_fe) { @@ -99,9 +99,9 @@ BOOST_AUTO_TEST_CASE(test_fe) } 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, "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, "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, "1.112_650_06e-17", value(1.11265006e-17)); } BOOST_AUTO_TEST_CASE(test_inf) diff --git a/tests/test_parse_inline_table.cpp b/tests/test_parse_inline_table.cpp index 57045bd..e1934a5 100644 --- a/tests/test_parse_inline_table.cpp +++ b/tests/test_parse_inline_table.cpp @@ -13,36 +13,36 @@ using namespace detail; BOOST_AUTO_TEST_CASE(test_inline_table) { - TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{}", table()); + TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{}", table()); { table t; t["foo"] = toml::value(42); t["bar"] = toml::value("baz"); - TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{foo = 42, bar = \"baz\"}", t); + TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{foo = 42, bar = \"baz\"}", t); } { table t; table t_sub; t_sub["name"] = toml::value("pug"); t["type"] = toml::value(t_sub); - TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{type.name = \"pug\"}", t); + TOML11_TEST_PARSE_EQUAL(parse_inline_table, "{type.name = \"pug\"}", t); } } BOOST_AUTO_TEST_CASE(test_inline_table_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{}", value(table())); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "{}", value(table())); { table t; t["foo"] = toml::value(42); 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, "{foo = 42, bar = \"baz\"}", value(t)); } { table t; table t_sub; t_sub["name"] = toml::value("pug"); 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, "{type.name = \"pug\"}", value(t)); } } diff --git a/tests/test_parse_integer.cpp b/tests/test_parse_integer.cpp index 6b5c515..f6547bb 100644 --- a/tests/test_parse_integer.cpp +++ b/tests/test_parse_integer.cpp @@ -25,14 +25,14 @@ BOOST_AUTO_TEST_CASE(test_decimal) 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, "+1234", toml::value( 1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1234", toml::value( -1234)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "+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, "123_456_789", toml::value(123456789)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "1234", toml::value( 1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "+1234", toml::value( 1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "-1234", toml::value( -1234)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_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, "+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, "123_456_789", toml::value(123456789)); } BOOST_AUTO_TEST_CASE(test_hex) @@ -50,15 +50,15 @@ BOOST_AUTO_TEST_CASE(test_hex) BOOST_AUTO_TEST_CASE(test_hex_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADBEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdeadbeef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADbeef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEAD_BEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_beef", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_BEEF", value(0xDEADBEEF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xFF", value(0xFF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x00FF", value(0xFF)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x0000FF", value(0xFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADBEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdeadbeef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEADbeef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xDEAD_BEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_beef", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xdead_BEEF", value(0xDEADBEEF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0xFF", value(0xFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x00FF", value(0xFF)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0x0000FF", value(0xFF)); } BOOST_AUTO_TEST_CASE(test_oct) @@ -70,9 +70,9 @@ BOOST_AUTO_TEST_CASE(test_oct) 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, "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, "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, "0o007", value(7)); } BOOST_AUTO_TEST_CASE(test_bin) @@ -85,8 +85,8 @@ BOOST_AUTO_TEST_CASE(test_bin) BOOST_AUTO_TEST_CASE(test_bin_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b10000", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b010000", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b01_00_00", value(16)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b111111", value(63)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b10000", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b010000", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b01_00_00", value(16)); + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "0b111111", value(63)); } diff --git a/tests/test_parse_string.cpp b/tests/test_parse_string.cpp index 60f9991..c223ba5 100644 --- a/tests/test_parse_string.cpp +++ b/tests/test_parse_string.cpp @@ -29,16 +29,16 @@ BOOST_AUTO_TEST_CASE(test_string) BOOST_AUTO_TEST_CASE(test_string_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"The quick brown fox jumps over the lazy dog\"", 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, "\'The quick brown fox jumps over the lazy dog\'", 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, "\"\"\"The quick brown fox \\\njumps over the lazy dog\"\"\"", 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, "'''The quick brown fox \njumps over the lazy dog'''", 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) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"GitHub Cofounder & CEO\\nLikes tater tots and beer.\"", 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, "\"192.168.1.1\"", value("192.168.1.1", string_t::basic)); #if defined(_MSC_VER) || defined(__INTEL_COMPILER) - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"\xE4\xB8\xAD\xE5\x9B\xBD\"", value("\xE4\xB8\xAD\xE5\x9B\xBD", string_t::basic)); #else - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"中国\"", value("中国", string_t::basic)); #endif - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"You'll hate me after this - #\"", value("You'll hate me after this - #", string_t::basic)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\" And when \\\"'s are in the along with # \\\"\"", 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) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"\"\"\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)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "\"\"\"\\\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)); } @@ -134,16 +134,16 @@ BOOST_AUTO_TEST_CASE(test_literal_string) BOOST_AUTO_TEST_CASE(test_literal_string_value) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "'C:\\Users\\nodejs\\templates'", value("C:\\Users\\nodejs\\templates", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "'\\\\ServerX\\admin$\\system32\\'", value("\\\\ServerX\\admin$\\system32\\", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "'Tom \"Dubs\" Preston-Werner'", value("Tom \"Dubs\" Preston-Werner", string_t::literal)); - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "'<\\i\\c*\\s*>'", 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) { - TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, + TOML11_TEST_PARSE_EQUAL_VALUE(parse_value, "'''I [dw]on't need \\d{2} apples'''", 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, "'''\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)); } diff --git a/tests/test_parse_table.cpp b/tests/test_parse_table.cpp index 13207b5..6d95ef0 100644 --- a/tests/test_parse_table.cpp +++ b/tests/test_parse_table.cpp @@ -21,7 +21,7 @@ BOOST_AUTO_TEST_CASE(test_normal_table) ); location loc("test", table); - const auto result = toml::detail::parse_ml_table(loc); + const auto result = toml::detail::parse_ml_table(loc); BOOST_CHECK(result.is_ok()); const auto data = result.unwrap(); @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(test_nested_table) ); location loc("test", table); - const auto result = toml::detail::parse_ml_table(loc); + const auto result = toml::detail::parse_ml_table(loc); BOOST_CHECK(result.is_ok()); const auto data = result.unwrap(); diff --git a/tests/test_value.cpp b/tests/test_value.cpp index 65b77b0..2cd3315 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -96,12 +96,12 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); BOOST_CHECK(v1.is_integer()); - BOOST_CHECK(v2.is_float()); + BOOST_CHECK(v2.is_floating()); BOOST_CHECK_EQUAL(v1.cast(), 42); BOOST_CHECK_EQUAL(v2.cast(), 3.14); BOOST_CHECK_EQUAL(v1.as_integer(), 42); - BOOST_CHECK_EQUAL(v2.as_float(), 3.14); + BOOST_CHECK_EQUAL(v2.as_floating(), 3.14); } BOOST_AUTO_TEST_CASE(test_value_integer) @@ -205,13 +205,13 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK(v2.is(toml::value_t::floating)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_float()); - BOOST_CHECK(v2.is_float()); + BOOST_CHECK(v1.is_floating()); + BOOST_CHECK(v2.is_floating()); BOOST_CHECK_EQUAL (v1.cast(), 3.14); BOOST_CHECK_CLOSE_FRACTION(v2.cast(), 3.14, 1e-2); - BOOST_CHECK_EQUAL (v1.as_float(), 3.14); - BOOST_CHECK_CLOSE_FRACTION(v2.as_float(), 3.14, 1e-2); + BOOST_CHECK_EQUAL (v1.as_floating(), 3.14); + BOOST_CHECK_CLOSE_FRACTION(v2.as_floating(), 3.14, 1e-2); v1 = 2.718f; v2 = 2.718; @@ -222,13 +222,13 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK(v2.is(toml::value_t::floating)); BOOST_CHECK(v1.is()); BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_float()); - BOOST_CHECK(v2.is_float()); + BOOST_CHECK(v1.is_floating()); + BOOST_CHECK(v2.is_floating()); BOOST_CHECK_CLOSE_FRACTION(v1.cast(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v2.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v1.as_float(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v2.as_float(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v1.as_floating(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v2.as_floating(), 2.718); toml::value v3(v1); toml::value v4(v2); @@ -241,13 +241,13 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK(v4.is(toml::value_t::floating)); BOOST_CHECK(v3.is()); BOOST_CHECK(v4.is()); - BOOST_CHECK(v3.is_float()); - BOOST_CHECK(v4.is_float()); + BOOST_CHECK(v3.is_floating()); + BOOST_CHECK(v4.is_floating()); BOOST_CHECK_CLOSE_FRACTION(v3.cast(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v4.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v3.as_float(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v4.as_float(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v3.as_floating(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v4.as_floating(), 2.718); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); @@ -258,13 +258,13 @@ BOOST_AUTO_TEST_CASE(test_value_float) BOOST_CHECK(v6.is(toml::value_t::floating)); BOOST_CHECK(v5.is()); BOOST_CHECK(v6.is()); - BOOST_CHECK(v5.is_float()); - BOOST_CHECK(v6.is_float()); + BOOST_CHECK(v5.is_floating()); + BOOST_CHECK(v6.is_floating()); BOOST_CHECK_CLOSE_FRACTION(v5.cast(), 2.718, 1e-3); BOOST_CHECK_EQUAL (v6.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v5.as_float(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v6.as_float(), 2.718); + BOOST_CHECK_CLOSE_FRACTION(v5.as_floating(), 2.718, 1e-3); + BOOST_CHECK_EQUAL (v6.as_floating(), 2.718); v1 = true; v2 = false; @@ -792,7 +792,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "qux"); BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_integer(), 42); - BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_float(), 3.14); + BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_floating(), 3.14); BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "qux"); @@ -806,7 +806,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); - BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_float(), 2.71); + BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_floating(), 2.71); BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_integer(), 54); BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "quux"); @@ -822,7 +822,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); BOOST_CHECK_EQUAL(v3.cast().at("bar").cast(), 54); BOOST_CHECK_EQUAL(v3.cast().at("baz").cast().str, "quux"); - BOOST_CHECK_EQUAL(v3.as_table().at("foo").as_float(), 2.71); + BOOST_CHECK_EQUAL(v3.as_table().at("foo").as_floating(), 2.71); BOOST_CHECK_EQUAL(v3.as_table().at("bar").as_integer(), 54); BOOST_CHECK_EQUAL(v3.as_table().at("baz").as_string().str, "quux"); From 407d9223f6d84e169a34d675544e4fd94fc41c19 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 22:01:47 +0900 Subject: [PATCH 049/162] feat: :boom: is_float -> is_floating --- toml/value.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/value.hpp b/toml/value.hpp index e8f5805..efe01e8 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -905,7 +905,7 @@ class basic_value bool is_uninitialized() const noexcept {return this->is(value_t::empty );} bool is_boolean() const noexcept {return this->is(value_t::boolean );} bool is_integer() const noexcept {return this->is(value_t::integer );} - bool is_float() const noexcept {return this->is(value_t::floating );} + bool is_floating() const noexcept {return this->is(value_t::floating );} bool is_string() const noexcept {return this->is(value_t::string );} bool is_offset_datetime() const noexcept {return this->is(value_t::offset_datetime);} bool is_local_datetime() const noexcept {return this->is(value_t::local_datetime );} From 7258c523340bb262d29daba68be06ca9539d2ce5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 3 Jun 2019 22:17:10 +0900 Subject: [PATCH 050/162] feat: enable to edit comments through memfun --- toml/value.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index efe01e8..eaaaf23 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -977,16 +977,14 @@ class basic_value array_type && as_array() && noexcept {return std::move(this->array_.value());} table_type && as_table() && noexcept {return std::move(this->table_.value());} - comment_type const& comments() const noexcept - { - return this->comments_; - } - source_location location() const { return source_location(this->region_info_); } + comment_type const& comments() const noexcept {return this->comments_;} + comment_type& comments() noexcept {return this->comments_;} + private: void cleanup() noexcept From a8b5fef827300951fdc1b5720e14d52a60dae24e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 6 Jun 2019 22:32:51 +0900 Subject: [PATCH 051/162] feat(WIP): add workaround to make literal compiles --- toml/literal.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/toml/literal.hpp b/toml/literal.hpp index 0e61cc9..5158495 100644 --- a/toml/literal.hpp +++ b/toml/literal.hpp @@ -53,7 +53,7 @@ inline ::toml::value operator""_toml(const char* str, std::size_t len) // 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(loc)) + if(auto data = ::toml::detail::parse_value<::toml::value>(loc)) { return data.unwrap(); } @@ -70,14 +70,14 @@ inline ::toml::value operator""_toml(const char* str, std::size_t len) // 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(loc)) + if(auto data = ::toml::detail::parse_toml_file<::toml::value>(loc)) { - loc.reset(loc.begin()); // rollback to the top of the literal - // skip needless characters for error message - skip_line::invoke(loc); // skip the first several needless lines - skip_ws::invoke(loc); // skip the first several needless whitespaces - return ::toml::value(std::move(data.unwrap()), - ::toml::detail::region>(std::move(loc))); + // TODO later I need to move this logic to parse_toml_file +// loc.reset(loc.begin()); // rollback to the top of the literal +// // skip needless characters for error message +// skip_line::invoke(loc); // skip the first several needless lines +// skip_ws::invoke(loc); // skip the first several needless whitespaces + return data.unwrap(); } else // none of them. { From e781545c539b22247b10f5ae28783aa475749bc6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 6 Jun 2019 22:34:08 +0900 Subject: [PATCH 052/162] feat(WIP): diable test for comments once because the interfaces would be changed a lot. --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 23faae6..07058c3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,7 @@ set(TEST_NAMES test_parse_key test_parse_table_key test_literals - test_comments +# test_comments test_get test_get_related_func test_parse_file From 9948549b6270575fc21ce034ff89a9fc3939c660 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 8 Jun 2019 19:53:50 +0900 Subject: [PATCH 053/162] fix: add missing template parameters --- toml/get.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index 86158ee..40f4a93 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -483,7 +483,7 @@ template class M, template class V> basic_value& find(basic_value& v, const key& ky) { - const auto& tab = v.template cast(); + auto& tab = v.template cast(); if(tab.count(ky) == 0) { throw std::out_of_range(detail::format_underline(concat_to_string( @@ -571,14 +571,16 @@ find(const basic_value& v, const ::toml::key& ky, Ts&& ... keys) return ::toml::find(::toml::find(v, ky), std::forward(keys)...); } template class M, template class V> + template class M, template class V, + typename ... Ts> basic_value& find(basic_value& v, const ::toml::key& ky, Ts&& ... keys) { return ::toml::find(::toml::find(v, ky), std::forward(keys)...); } template class M, template class V> + template class M, template class V, + typename ... Ts> basic_value&& find(basic_value&& v, const ::toml::key& ky, Ts&& ... keys) { @@ -594,14 +596,16 @@ find(const basic_value& v, const ::toml::key& ky, Ts&& ... keys) return ::toml::find(::toml::find(v, ky), std::forward(keys)...); } template class M, template class V> + template class M, template class V, + typename ... Ts> decltype(::toml::get(std::declval&>())) find(basic_value& v, const ::toml::key& ky, Ts&& ... keys) { return ::toml::find(::toml::find(v, ky), std::forward(keys)...); } template class M, template class V> + template class M, template class V, + typename ... Ts> decltype(::toml::get(std::declval&&>())) find(basic_value&& v, const ::toml::key& ky, Ts&& ... keys) { From eb4eca86db715d5ebad0efb2772e1bf6b7d2acf9 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 16:11:05 +0900 Subject: [PATCH 054/162] feat: :boom: change comment interface in region --- toml/region.hpp | 146 +++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 76 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 923da9b..c3189da 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -54,9 +54,7 @@ struct region_base // number of characters in the line after the region virtual std::size_t after() const noexcept {return 0;} - virtual std::string comment_before() const {return "";} // just before - virtual std::string comment_inline() const {return "";} // in the same line - virtual std::string comment() const {return "";} // concatenate + virtual std::vector comments()const {return {};} // ```toml // # comment_before // key = "value" # comment_inline @@ -289,90 +287,86 @@ struct region final : public region_base std::string name() const override {return source_name_;} - std::string comment_before() const override + std::vector comments() const override { - auto iter = this->line_begin(); // points the first element - std::vector> comments; - while(iter != this->begin()) - { - iter = std::prev(iter); - using rev_iter = std::reverse_iterator; - auto line_before = std::find(rev_iter(iter), rev_iter(this->begin()), - '\n').base(); - // range [line_before, iter) represents the previous line + // assuming the current region (`*this`) points a value. + // ```toml + // a = "value" + // ^^^^^^^- this region + // ``` + using rev_iter = std::reverse_iterator; - auto comment_found = std::find(line_before, iter, '#'); - if(iter != comment_found && std::all_of(line_before, comment_found, - [](const char c) noexcept -> bool { - return c == ' ' || c == '\t'; - })) + std::vector com{}; + { + // find comments just before the current region. + // ```toml + // # this should be collected. + // # this also. + // a = value # not this. + // ``` + auto iter = this->line_begin(); // points the first character + while(iter != this->begin()) { - // the line before this range contains only a comment. - comments.push_back(std::make_pair(comment_found, iter)); + 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. + com.push_back(make_string(std::next(comment_found), iter)); + } + else + { + break; + } + iter = line_start; } - else - { - break; - } - iter = line_before; } - - std::string com; - for(auto i = comments.crbegin(), e = comments.crend(); i!=e; ++i) { - if(i != comments.crbegin()) {com += '\n';} - com += std::string(i->first, i->second); - } - return com; - } - - std::string comment_inline() const override - { - if(this->contain_newline()) - { - std::string com; - // check both the first and the last line. - const auto first_line_end = - std::find(this->line_begin(), this->last(), '\n'); - const auto first_comment_found = - std::find(this->line_begin(), first_line_end, '#'); - - if(first_comment_found != first_line_end) - { - com += std::string(first_comment_found, first_line_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 last_comment_found = std::find(this->last(), this->line_end(), '#'); - if(last_comment_found != this->line_end()) + if(last_comment_found != this->line_end()) // '#' found { - if(!com.empty()){com += '\n';} - com += std::string(last_comment_found, this->line_end()); + com.push_back(make_string(last_comment_found, this->line_end())); } - return com; - } - const auto comment_found = - std::find(this->line_begin(), this->line_end(), '#'); - return std::string(comment_found, this->line_end()); - } - - std::string comment() const override - { - std::string com_bef = this->comment_before(); - std::string com_inl = this->comment_inline(); - if(!com_bef.empty() && !com_inl.empty()) - { - com_bef += '\n'; - return com_bef + com_inl; - } - else if(com_bef.empty()) - { - return com_inl; - } - else - { - return com_bef; } + return com; } private: From 558349170d7a16837f99046f9fe6670fec78b4e2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 17:11:49 +0900 Subject: [PATCH 055/162] fix: correct the order and remove last CR --- toml/region.hpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index c3189da..2f5b0b9 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -309,6 +309,7 @@ struct region final : public region_base { 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(); @@ -327,7 +328,9 @@ struct region final : public region_base })) { // unwrap the first '#' by std::next. - com.push_back(make_string(std::next(comment_found), iter)); + auto str = make_string(std::next(comment_found), iter); + if(str.back() == '\r') {str.pop_back();} + com.push_back(std::move(str)); } else { @@ -336,6 +339,12 @@ struct region final : public region_base iter = line_start; } } + + if(com.size() > 1) + { + std::reverse(com.begin(), com.end()); + } + { // find comments just after the current region. // ```toml @@ -359,11 +368,14 @@ struct region final : public region_base // 3.14 # do this if you need a comment here. // ] // ``` - const auto last_comment_found = + const auto comment_found = std::find(this->last(), this->line_end(), '#'); - if(last_comment_found != this->line_end()) // '#' found + if(comment_found != this->line_end()) // '#' found { - com.push_back(make_string(last_comment_found, this->line_end())); + // 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; From a6706f7879dda664468df9a7ed2f42cc8c5c1dda Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 17:12:30 +0900 Subject: [PATCH 056/162] fix: templatize internal function for value --- toml/parser.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index ab29d76..6cc028b 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1086,8 +1086,8 @@ parse_table_key(location& loc); // Here, it parses region of `tab->at(k)` as a table key and check the depth // of the key. If the key region points deeper node, it would be allowed. // Otherwise, the key points the same node. It would be rejected. -template -bool is_valid_forward_table_definition(const value& fwd, +template +bool is_valid_forward_table_definition(const Value& fwd, Iterator key_first, Iterator key_curr, Iterator key_last) { location def("internal", detail::get_region(fwd).str()); From 5726d103390e04a07fda5a0fb5a5fe748978745e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 17:13:02 +0900 Subject: [PATCH 057/162] feat: save comment information in value --- toml/value.hpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 7683382..578cdb2 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -450,7 +450,8 @@ class basic_value template basic_value(boolean b, detail::region reg) : type_(value_t::boolean), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->boolean_, b); } @@ -474,7 +475,8 @@ class basic_value >::value, std::nullptr_t>::type = nullptr> basic_value(T i, detail::region reg) : type_(value_t::integer), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->integer_, static_cast(i)); } @@ -506,7 +508,8 @@ class basic_value std::is_floating_point::value, std::nullptr_t>::type = nullptr> basic_value(T f, detail::region reg) : type_(value_t::floating), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->floating_, f); } @@ -533,7 +536,8 @@ class basic_value template basic_value(toml::string s, detail::region reg) : type_(value_t::string), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->string_, std::move(s)); } @@ -622,7 +626,8 @@ class basic_value template basic_value(const local_date& ld, detail::region reg) : type_(value_t::local_date), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->local_date_, ld); } @@ -646,7 +651,8 @@ class basic_value template basic_value(const local_time& lt, detail::region reg) : type_(value_t::local_time), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->local_time_, lt); } @@ -686,7 +692,8 @@ class basic_value template basic_value(const local_datetime& ldt, detail::region reg) : type_(value_t::local_datetime), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->local_datetime_, ldt); } @@ -710,7 +717,8 @@ class basic_value template basic_value(const offset_datetime& odt, detail::region reg) : type_(value_t::offset_datetime), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->offset_datetime_, odt); } @@ -748,7 +756,8 @@ class basic_value template basic_value(const array_type& ary, detail::region reg) : type_(value_t::array), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->array_, ary); } @@ -822,7 +831,8 @@ class basic_value template basic_value(const table_type& tab, detail::region reg) : type_(value_t::table), - region_info_(std::make_shared>(std::move(reg))) + region_info_(std::make_shared>(std::move(reg))), + comments_(region_info_->comments()) { assigner(this->table_, tab); } From 177022b2cb1253c6a87d02dd388e048f223a5dc7 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 17:13:25 +0900 Subject: [PATCH 058/162] test: update tests for comment --- tests/CMakeLists.txt | 2 +- tests/test_comments.cpp | 145 ++++++++++++++++++++++------------------ 2 files changed, 82 insertions(+), 65 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 07058c3..23faae6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,7 +21,7 @@ set(TEST_NAMES test_parse_key test_parse_table_key test_literals -# test_comments + test_comments test_get test_get_related_func test_parse_file diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index a6325e4..34a6117 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -10,45 +10,46 @@ BOOST_AUTO_TEST_CASE(test_comment_before) { - using namespace toml::literals::toml_literals; { - const toml::value v = u8R"( + const std::string file = u8R"( # comment for a. a = 42 # comment for b. b = "baz" - )"_toml; + )"; + std::istringstream iss(file); + const auto v = toml::parse(iss); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_before(), u8"# comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_before(), u8"# comment for b."); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_inline(), ""); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_inline(), ""); + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment(), u8"# comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment(), u8"# comment for b."); + BOOST_CHECK_EQUAL(a.comments().size(), 1u); + BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); + BOOST_CHECK_EQUAL(b.comments().size(), 1u); + BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); } - { - const toml::value v = u8R"( + const std::string file = u8R"( # comment for a. # another comment for a. a = 42 # comment for b. # also comment for b. b = "baz" - )"_toml; + )"; - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_before(), u8R"(# comment for a. -# another comment for a.)"); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_before(), u8R"(# comment for b. -# also comment for b.)"); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_inline(), u8""); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_inline(), u8""); + std::istringstream iss(file); + const auto v = toml::parse(iss); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment(), u8R"(# comment for a. -# another comment for a.)"); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment(), u8R"(# comment for b. -# also comment for b.)"); + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + + BOOST_CHECK_EQUAL(a.comments().size(), 2u); + BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); + BOOST_CHECK_EQUAL(a.comments().back(), u8" another comment for a."); + BOOST_CHECK_EQUAL(b.comments().size(), 2u); + BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); + BOOST_CHECK_EQUAL(b.comments().back(), u8" also comment for b."); } } @@ -56,48 +57,46 @@ BOOST_AUTO_TEST_CASE(test_comment_inline) { using namespace toml::literals::toml_literals; { - const toml::value v = u8R"( + const std::string file = u8R"( a = 42 # comment for a. b = "baz" # comment for b. - )"_toml; + )"; - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_before(), ""); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_before(), ""); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_inline(), u8"# comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_inline(), u8"# comment for b."); + std::istringstream iss(file); + const auto v = toml::parse(iss); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment(), u8"# comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment(), u8"# comment for b."); + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + + BOOST_CHECK_EQUAL(a.comments().size(), 1u); + BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); + BOOST_CHECK_EQUAL(b.comments().size(), 1u); + BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); } { - const toml::value v = u8R"( - a = [ # comment for a. + const std::string file = u8R"( + a = [ 42, - ] # this also. - b = [ # comment for b. - "bar", - ] - c = [ - 3.14, # this is not a comment for c, but 3.14. - ] # comment for c. - )"_toml; + ] # comment for a. + b = [ + "bar", # this is not a comment for b, but "bar" + ] # this is a comment for b. + )"; - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_before(), ""); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_before(), ""); - BOOST_CHECK_EQUAL(toml::find(v, "c").comment_before(), ""); + std::istringstream iss(file); + const auto v = toml::parse(iss); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_inline(), u8R"(# comment for a. -# this also.)"); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_inline(), u8"# comment for b."); - BOOST_CHECK_EQUAL(toml::find(v, "c").comment_inline(), u8"# comment for c."); + const auto& a = toml::find(v, "a"); + const auto& b = toml::find(v, "b"); + const auto& b0 = b.as_array().at(0); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment(), u8R"(# comment for a. -# this also.)"); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment(), u8"# comment for b."); - BOOST_CHECK_EQUAL(toml::find(v, "c").comment(), u8"# comment for c."); - - const auto& c0 = toml::find(v, "c").at(0); - BOOST_CHECK_EQUAL(c0.comment(), u8"# this is not a comment for c, but 3.14."); + BOOST_CHECK_EQUAL(a.comments().size(), 1u); + BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); + BOOST_CHECK_EQUAL(b.comments().size(), 1u); + BOOST_CHECK_EQUAL(b.comments().front(), u8" this is a comment for b."); + BOOST_CHECK_EQUAL(b0.comments().size(), 1u); + BOOST_CHECK_EQUAL(b0.comments().front(), + u8" this is not a comment for b, but \"bar\""); } } @@ -105,21 +104,39 @@ BOOST_AUTO_TEST_CASE(test_comment_both) { using namespace toml::literals::toml_literals; { - const toml::value v = u8R"( + const std::string file = u8R"( # comment for a. a = 42 # inline comment for a. # comment for b. b = "baz" # inline comment for b. - )"_toml; + # comment for c. + c = [ # this comment will be ignored + # comment for the first element. + 10 # this also. + ] # another comment for c. + )"; - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_before(), "# comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_before(), "# comment for b."); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment_inline(), "# inline comment for a."); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment_inline(), "# inline comment for b."); + std::istringstream iss(file); + const auto v = toml::parse(iss); - BOOST_CHECK_EQUAL(toml::find(v, "a").comment(), u8R"(# comment for a. -# inline comment for a.)"); - BOOST_CHECK_EQUAL(toml::find(v, "b").comment(), u8R"(# comment for b. -# inline comment for b.)"); + 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_CHECK_EQUAL(a.comments().size(), 2u); + BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); + BOOST_CHECK_EQUAL(a.comments().back(), u8" inline comment for a."); + BOOST_CHECK_EQUAL(b.comments().size(), 2u); + BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); + BOOST_CHECK_EQUAL(b.comments().back(), u8" inline comment for b."); + + BOOST_CHECK_EQUAL(c.comments().size(), 2u); + BOOST_CHECK_EQUAL(c.comments().front(), u8" comment for c."); + BOOST_CHECK_EQUAL(c.comments().back(), u8" another comment for c."); + + BOOST_CHECK_EQUAL(c0.comments().size(), 2u); + BOOST_CHECK_EQUAL(c0.comments().front(), u8" comment for the first element."); + BOOST_CHECK_EQUAL(c0.comments().back(), u8" this also."); } } From 9acc55a7ac0a11cd1c5b509586376ae42b260e28 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 17:18:25 +0900 Subject: [PATCH 059/162] test: add test for discard_comment --- tests/test_comments.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 34a6117..bf4b200 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -140,3 +140,32 @@ BOOST_AUTO_TEST_CASE(test_comment_both) BOOST_CHECK_EQUAL(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_CHECK(a.comments().empty()); + BOOST_CHECK(b.comments().empty()); + BOOST_CHECK(c.comments().empty()); + BOOST_CHECK(c0.comments().empty()); +} + From 64dc086878350c9729bcc236a5320bd929c6cb61 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 19:50:31 +0900 Subject: [PATCH 060/162] doc(WIP): re-write README --- README.md | 991 +++++++++++++++++++++++++++--------------------------- 1 file changed, 501 insertions(+), 490 deletions(-) diff --git a/README.md b/README.md index b7a6d58..7163a8d 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,14 @@ You can see the error messages about invalid files and serialization results of int main() { - const auto data = toml::parse("example.toml"); + const auto data = toml::parse("example.toml"); // title = "an example toml file" - std::string title = toml::get(data.at("title")); + std::string title = toml::find(data, "title"); std::cout << "the title is " << title << std::endl; // nums = [1, 2, 3, 4, 5] - std::vector nums = toml::get>(data.at("nums")); + std::vector nums = toml::find>(data, "nums"); std::cout << "the length of `nums` is" << nums.size() << std::endl; return 0; @@ -46,19 +46,23 @@ int main() - [Integration](#integration) - [Decoding a toml file](#decoding-a-toml-file) - [In the case of syntax error](#in-the-case-of-syntax-error) -- [Getting a toml value](#getting-a-toml-value) +- [Finding a toml value](#getting-a-toml-value) - [In the case of type error](#in-the-case-of-type-error) -- [Getting an array](#getting-an-array) -- [Getting a table](#getting-a-table) - [Dotted keys](#dotted-keys) -- [Getting an array of tables](#getting-an-array-of-tables) -- [Cost of conversion](#cost-of-conversion) -- [Getting datetime and its variants](#getting-datetime-and-its-variants) +- [Casting a toml value](#casting-a-toml-value) +- [Checking value type](#checking-value-type) +- [More about conversion](#more-about-conversion) + - [Getting an array](#getting-an-array) + - [Getting a table](#getting-a-table) + - [Getting an array of tables](#getting-an-array-of-tables) + - [Cost of conversion](#cost-of-conversion) + - [Getting datetime and its variants](#getting-datetime-and-its-variants) - [Getting with a fallback](#getting-with-a-fallback) - [Expecting conversion](#expecting-conversion) -- [Finding a value from a table](#finding-a-value-from-a-table) -- [Checking value type](#checking-value-type) - [Visiting a toml::value](#visiting-a-tomlvalue) +- [Constructing a toml::value](#constructing-a-tomlvalue) +- [Preserving Comments](#preserving-comments) +- [Customizing container](#customizing-container) - [TOML literal](#toml-literal) - [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) @@ -66,6 +70,7 @@ int main() - [Getting comments related to a value](#getting-comments) - [Serializing TOML data](#serializing-toml-data) - [Underlying types](#underlying-types) +- [Breaking Changes from v2](#breaking-changes-from-v2) - [Running Tests](#running-tests) - [Contributors](#contributors) - [Licensing Terms](#licensing-terms) @@ -81,12 +86,14 @@ Just include the file after adding it to the include path. int main() { const auto data = toml::parse("example.toml"); - const auto title = toml::get(data.at("title")); + const auto title = toml::find(data, "title"); std::cout << "the title is " << title << std::endl; return 0; } ``` +The convenient way is to add this repository as a git-submodule. + ## Decoding a toml file To parse a toml file, the only thing you have to do is @@ -97,7 +104,7 @@ const std::string fname("sample.toml"); const toml::table data = toml::parse(fname); ``` -If it encounters a file open error, it will throw `std::runtime_error`. +If it encounters an error while opening a file, it will throw `std::runtime_error`. You can also pass a `std::istream` to the `toml::parse` function. To show a filename in an error message, it is recommended to pass the filename @@ -109,15 +116,15 @@ assert(ifs.good()); const auto data = toml::parse(ifs, /*optional*/ "sample.toml"); ``` -Note that on Windows, if a file is opened in text-mode, CRLF ("\r\n") will -automatically be converted to LF ("\n") and this causes inconsistency between -file size and the contents that would be read. This causes weird error. -To use a file stream with `toml::parse` on Windows, don't forget to open it -in binary mode. +**Note**: When you are **on Windows, open a file in binary mode**. +If a file is opened in text-mode, CRLF ("\r\n") will automatically be +converted to LF ("\n") and this causes inconsistency between file size +and the contents that would be read. This causes weird error. ### In the case of syntax error -If there is a syntax error in a toml file, `toml::parse` will throw `toml::syntax_error`. +If there is a syntax error in a toml file, `toml::parse` will throw +`toml::syntax_error` that inherits `std::exception`. toml11 has clean and informative error messages inspired by Rust and it looks like the following. @@ -148,10 +155,22 @@ Since the error message generation is generally a difficult task, the current status is not ideal. If you encounter a weird error message, please let us know and contribute to improve the quality! -## Getting a toml value +### Invalid UTF-8 codepoints + +It throws `syntax_error` if a value of an escape sequence +representing unicode character is not a valid UTF-8 codepoint. + +```console + what(): [error] toml::read_utf8_codepoint: input codepoint is too large. + --> utf8.toml + 1 | exceeds_unicode = "\U0011FFFF example" + | ^--------- should be in [0x00..0x10FFFF] +``` + +## Finding a toml value from a table After parsing successfully, you can obtain the values from the result of -`toml::parse` using `toml::get` function. +`toml::parse` using `toml::find` function. ```toml # sample.toml @@ -165,38 +184,75 @@ key = "value" ``` cpp const auto data = toml::parse("sample.toml"); -const auto answer = toml::get(data.at("answer")); -const auto pi = toml::get(data.at("pi")); -const auto numbers = toml::get>(data.at("numbers")); -const auto timepoint = toml::get(data.at("time")); -const auto tab = toml::get(data.at("tab")); -const auto key = toml::get( tab.at("key")); +const auto answer = toml::find(data, "answer"); +const auto pi = toml::find(data, "pi"); +const auto numbers = toml::find>(data, "numbers"); +const auto timepoint = toml::find(data, "time"); +const auto tab = toml::find(data, "tab"); +const auto key = toml::find(tab, "key"); +``` + +If the value does not exist, `toml::find` throws an error with the location of +the table. + +```console +terminate called after throwing an instance of 'std::out_of_range' + what(): [error] key "answer" not found + --> example.toml + 6 | [tab] + | ~~~~~ in this table ``` When you pass an exact TOML type that does not require type conversion, -`toml::get` returns a reference through which you can modify the content. +`toml::get` returns a reference without copying the value. ```cpp -auto data = toml::parse("sample.toml"); -auto& answer = toml::get(data["answer"]); // get reference -answer = 6 * 9; // write to data.answer -std::cout << toml::get(data.at("answer")) << std::endl; // 54 +const auto data = toml::parse("sample.toml"); +const auto& answer = toml::find(data, "answer"); ``` If the specified type requires conversion, you can't take a reference to the value. See also [underlying types](#underlying-types). -NOTE: To enable to get a reference, conversions between Float and Integer are not supported. - -After C++17, you can use `std::string_view` to get a string from a `toml::value`. +By default, `toml::find` returns a `toml::value`. ```cpp -const auto sv = toml::get(tab.at("key")); +const toml::value& answer = toml::find(data, "answer"); +``` + +**NOTE**: For some technical reason, automatic conversion between `integer` and +`floating` is not supported. If you want to get a floating value even if a value +has integer value, you need to convert it manually after obtaining a value. + +---- + +There are several ways to find a value buried in a deep recursion of tables. + +First, you can call `toml::find` as many as you need. + +```cpp +// # expecting the following example.toml +// answer.to.the.ultimate.question = 42 +// # is equivalent to {"answer": {"to":{"the":{"ultimate:{"question":42}}}}} + +const toml::table data = toml::parse("example.toml"); +const int a = toml::find(toml::find(toml::find(toml::find(toml::find( + data, "answer"), "to"), "the"), "ultimate"), "question"); +``` + +But it is a bother. Alternatively, you can pass several keys to `toml::find` to +find the value. + +```cpp +const toml::value data = toml::parse("example.toml"); +const int a = toml::find(data, "answer", "to", "the", "ultimate", "question"); ``` ### In the case of type error -If you pass an invalid type to `toml::get`, `toml::type_error` will be thrown. +If the specified type differs from the actual value contained, it throws +`toml::type_error` that inherits `std::exception`. + Similar to the case of syntax error, toml11 also displays clean error messages. The error message when you choose `int` to get `string` value would be like this. @@ -208,94 +264,13 @@ terminate called after throwing an instance of 'toml::type_error' | ~~~~~~~~~~~~~~ the actual type is string ``` -NOTE: In order to show this kind of error message, all the toml values have -pointers to represent its range in a file. The entire contents of a file is +**NOTE**: In order to show this kind of error message, all the toml values have +a pointer to represent its range in a file. The entire contents of a file is shared by `toml::value`s and remains on the heap memory. It is recommended to destruct all the `toml::value` classes after configuring your application if you have a large TOML file compared to the memory resource. -## Getting an array - -You can get any kind of `container` class from a `toml::array` -except for `map`-like classes. - -``` cpp -// # sample.toml -// numbers = [1,2,3] - -const auto vc = toml::get >(data.at("numbers")); -const auto ls = toml::get >(data.at("numbers")); -const auto dq = toml::get >(data.at("numbers")); -const auto ar = toml::get>(data.at("numbers")); -// if the size of data.at("numbers") is larger than that of std::array, -// it will throw toml::type_error because std::array is not resizable. -``` - -Surprisingly, you can also get `std::pair`s and `std::tuple`s from `toml::array`. - -```cpp -const auto tp = toml::get>(data.at("numbers")); -``` - -This functionality is helpful when you have the following toml file. - -```toml -array_of_arrays = [[1, 2, 3], ["foo", "bar", "baz"]] # toml allows this -``` - -What is the corresponding C++ type? Obviously, it is a `std::pair` of `std::vector`s. - -```cpp -const auto aofa = toml::get< - std::pair, std::vector> - >(data.at("array_of_arrays")); -``` - -If you don't know the type of the elements, you can use `toml::array`, -which is a `std::vector` of `toml::value`, instead. - -```cpp -const auto aofa = toml::get(data.at("array_of_arrays")); -const auto first = toml::get>(aofa.at(0)); -``` - -See also [expecting conversion](#expecting-conversion) -and [checking-value-type](#checking-value-type). - -## Getting a table - -`toml::table` is a key component of this library, which is an alias of -a `std::unordered_map` from `toml::key (a.k.a. std::string)` to `toml::value`. -`toml::parse` returns this. - -Since it is just an alias of `std::unordered_map`, it has all the functionalities -that `std::unordered_map` has, e.g. `operator[]`, `count`, and `find`. - -```cpp -toml::table data = toml::parse("example.toml"); -if(data.count("title") != 0) -{ - data["title"] = std::string("TOML example"); -} -``` - -When all the values of the table have the same type, toml11 allows you to -convert a `toml::table` to a `map` that contains the convertible type. - -```toml -[tab] -key1 = "foo" # all the values are -key2 = "bar" # toml String -``` - -```cpp -const auto data = toml::parse("sample.toml"); -const auto tab = toml::get>(data.at("tab")); -std::cout << tab["key1"] << std::endl; // foo -std::cout << tab["key2"] << std::endl; // bar -``` - -## Dotted keys +### Dotted keys TOML v0.5.0 has a new feature named "dotted keys". You can chain keys to represent the structure of the data. @@ -313,338 +288,88 @@ color = "orange" shape = "round" ``` -You can get both of the above formats with the same c++ code. +You can get both of the above tables with the same c++ code. ```cpp -const auto physical = toml::get(data.at("physical")); -const auto color = toml::get(physical.at("color")); +const auto physical = toml::find(data, "physical"); +const auto color = toml::find(physical, "color"); ``` -## Getting an array of tables +The following code does not work for the above toml file. -An array of tables is just an array of tables. -You can get it completely in the same way as the other arrays and tables. +```cpp +const auto color = toml::find(data, "physical.color"); +``` + +The above code works with the following toml file. ```toml -# sample.toml -array_of_inline_tables = [{key = "value1"}, {key = "value2"}, {key = "value3"}] - -[[array_of_tables]] -key = "value4" -[[array_of_tables]] -key = "value5" -[[array_of_tables]] -key = "value6" +"physical.color" = "orange" ``` -```cpp -const auto data = toml::parse("sample.toml"); -const auto aot1 = toml::get>(data.at("array_of_inline_tables")); -const auto aot2 = toml::get>(data.at("array_of_tables")); -``` +## Casting a toml value -## Cost of conversion +### `toml::get` -Although `toml::get` is convenient, it has additional copy-cost because -it copies data contained in `toml::value` to the user-specified type. -Of course in some cases this overhead is not ignorable. +`toml::parse` returns `toml::value`. `toml::value` is a union type that can +contain one of the following types. -```cpp -// the following code constructs a std::vector. -// it requires heap allocation for vector and element conversion. -const auto array = toml::get>(data.at("foo")); -``` +- `toml::boolean` (`bool`) +- `toml::integer` (`std::int64_t`) +- `toml::floating` (`double`) +- `toml::string` (a type convertible to std::string) +- `toml::local_date` +- `toml::local_time` +- `toml::local_datetime` +- `toml::offset_datetime` +- `toml::array` (by default, `std::vector`) + - It depends. See [customize toml::value](#customize-toml-value) for detail. +- `toml::table` (by default, `std::unordered_map`) + - It depends. See [customize toml::value](#customize-toml-value) for detail. -By passing the exact types, `toml::get` returns reference that has no overhead. +To get a value inside, you can use `toml::get()`. The usage is the same as +`toml::find` (actually, `toml::find` internally uses `toml::get`). ``` cpp -const auto& tab = toml::get(data.at("tab")); -const auto& numbers = toml::get(data.at("numbers")); +const toml::value data = toml::parse("sample.toml"); +const toml::value answer_ = toml::get(data).at("answer") +const std::int64_t answer = toml::get(answer_); ``` -In this case you need to call `toml::get` each time you access to -the element of `toml::array` because `toml::array` is an array of `toml::value`. +When you pass an exact TOML type that does not require type conversion, +`toml::get` returns a reference through which you can modify the content. ```cpp -const auto& num0 = toml::get(numbers.at(0)); -const auto& num1 = toml::get(numbers.at(1)); -const auto& num2 = toml::get(numbers.at(2)); +toml::integer& answer = toml::get(answer_); +answer = 6 * 9; // write to data.answer. now `answer_` contains 54. ``` -## Getting datetime and its variants +If the specified type requires conversion, you can't take a reference to the value. +See also [underlying types](#underlying-types). -TOML v0.5.0 has 4 different datetime objects, `local_date`, `local_time`, -`local_datetime`, and `offset_datetime`. +It also throws a `toml::type_error` if the type differs. -Since `local_date`, `local_datetime`, and `offset_datetime` represent a time -point, you can convert them to `std::chrono::system_clock::time_point`. +### `as_xxx` -Contrary, `local_time` does not represents a time point because they lack a -date information, but it can be converted to `std::chrono::duration` that -represents a duration from the beginning of the day, `00:00:00.000`. - -```toml -date = 2018-12-23 -time = 12:30:00 -l_dt = 2018-12-23T12:30:00 -o_dt = 2018-12-23T12:30:00+09:30 -``` +You can also use a member function to cast a value. ```cpp -const auto data = toml::parse("sample.toml"); - -const auto date = toml::get(data.at("date")); -const auto l_dt = toml::get(data.at("l_dt")); -const auto o_dt = toml::get(data.at("o_dt")); - -const auto time = toml::get(data.at("time")); // 12 * 60 + 30 min +const std::int64_t answer = data.as_table().at("answer").as_integer(); ``` -toml11 contains datetime as its own struct. -You can see the definitions in [toml/datetime.hpp](toml/datetime.hpp). - -## Getting with a fallback - -`toml::get_or` returns a default value if `toml::get` failed. +It also throws a `toml::type_error` if the type differs. If you are sure that +the value `v` contains a value of the specified type, you can suppress checking +by passing `std::nothrow`. ```cpp -toml::value v("foo"); // v contains String -const int value = toml::get_or(v, 42); // conversion fails. it returns 42. -``` - -`toml::get_or` automatically deduces what type you want to get from -the default value you passed. - -To get a reference through this function, take care about the default value. - -```cpp -toml::value v("foo"); // v contains String -toml::integer& i = toml::get_or(v, 42); // does not work because binding `42` - // to `integer&` is invalid -toml::integer opt = 42; -toml::integer& i = toml::get_or(v, opt); // this works. -``` - -## Expecting conversion - -By using `toml::expect`, you will get your expected value or an error message -without throwing `toml::type_error`. - -```cpp -const auto value = toml::expect(data.at("title")); -if(value.is_ok()) { - std::cout << value.unwrap() << std::endl; -} else { - std::cout << value.unwrap_err() << std::endl; -} -``` - -Also, you can pass a function object to modify the expected value. - -```cpp -const auto value = toml::expect(data.at("number")) - .map(// function that receives expected type (here, int) - [](const int number) -> double { - return number * 1.5 + 1.0; - }).unwrap_or(/*default value =*/ 3.14); -``` - -## Finding a value from a table - -toml11 provides utility function to find a value from `toml::value` and `toml::table`. - -```cpp -const auto data = toml::parse("example.toml"); -// find a value named "num" from `data`. -const auto num = toml::find(data, "num"); -``` - -If the value does not exist, it throws `std::out_of_range` with an error message. -But, since `toml::table` is just an alias of `std::unordered_map`, -you need to pass a name to the function to show the name in the exception. - -```cpp -const auto num = toml::find(data, "num", "example.toml"); -``` - -```console -terminate called after throwing an instance of 'std::out_of_range' - what(): [error] key "num" not found in example.toml -# ^^^^^^^^^^^^ this part -``` - -Of course, you can do this in your own way with `toml::get` because -it just searches an `unordered_map` and returns a value if it exists. - -```cpp -const toml::table data = toml::parse("example.toml"); -if(data.count("num") == 1) -{ - const auto num = toml::get(data.at("num")); - // more stuff ... -} -``` - ----- - -You can also use this with a `toml::value` that is expected to contain a `toml::table`. -It automatically casts the `toml::value` to a `toml::table`. If it failed to cast, -it would throw a `toml::type_error`. - -```cpp -// # expecting the following example.toml -// [table] -// num = 42 -const toml::table data = toml::parse("example.toml"); -const toml::value table = data.at("table"); -const auto num = toml::find(table, "num"); -``` - -In this case, because the `toml::value table` knows the locatoin of itself, -you don't need to pass the name to show it in an error message. -`toml::find` will automatically format an error message with the location of the table. - -```console -terminate called after throwing an instance of 'std::out_of_range' - what(): [error] key "num" not found - --> example.toml - 3 | [table] - | ~~~~~~~ in this table -``` - -The default return value of the `toml::find` is a `toml::value`. - -```cpp -const toml::value& subtable = toml::find(table, "subtable"); -``` - -There are several ways to find a value buried in a deep recursion of tables. - -First, you can call `toml::find` as many as you need. - -```cpp -// # expecting the following example.toml -// answer.to.the.ultimate.question = 42 -// # is equivalent to {"answer": {"to":{"the":{"ultimate:{"question":42}}}}} - -const toml::table data = toml::parse("example.toml"); -const int a = toml::find(toml::find(toml::find(toml::find(toml::find( - data, "answer"), "to"), "the"), "ultimate"), "question"); -``` - -But it is a bother. - -After toml11 v2.4.0, you can pass a `toml::value` and as many number of keys as you want. - -```cpp -const toml::table data = toml::parse("example.toml"); -const int a = toml::find(data.at("answer"), "to", "the", "ultimate", "question"); -``` - -__NOTE__: -Currently, this function does not support `toml::table` because of some -technical reason. Please make sure that the type of the first argument is -`toml::value`. The main reason is that the `toml::table` may take an additional string -as the third argumnet to show its location in an error message. And the -most confusing part is that `toml::parse` returns `toml::table`, not a -`toml::value`. This confusing API will hopefully be resolved in the next -major update, v3 (it will contain some unavoidable breaking changes). - ----- - -There is another utility function, `toml::find_or`. -It is almost same as `toml::find`, but returns a default value if the value is -not found or has a different type, like `toml::get_or`. - -```cpp -const auto data = toml::parse("example.toml"); -const auto num = toml::find_or(data.at("table"), "num", 42); -``` - -## Checking value type - -You can check what type of value does `toml::value` contains by `is_*` function. - -```cpp -toml::value v = /* ... */; -if(v.is_integer()) -{ - std::cout << "value is an integer" << std::endl; -} -``` - -The complete list of the functions is below. - -```cpp -namespace toml { -class value { - // ... - bool is_boolean() const noexcept; - bool is_integer() const noexcept; - bool is_floating() const noexcept; - bool is_string() const noexcept; - bool is_offset_datetime() const noexcept; - bool is_local_datetime() const noexcept; - bool is_local_date() const noexcept; - bool is_local_time() const noexcept; - bool is_array() const noexcept; - bool is_table() const noexcept; - bool is_uninitialized() const noexcept; - // ... -}; -} // toml -``` - -__NOTE__: `is_float` is marked as deprecated since v2.4.0 to make the function names consistent with snake case typenames. Please use `is_floating` instead. - -Also, you can get `enum class` value from `toml::value`. - -```cpp -switch(data.at("something").type()) -{ - case toml::value_t::Integer: /*do some stuff*/ ; break; - case toml::value_t::Float : /*do some stuff*/ ; break; - case toml::value_t::String : /*do some stuff*/ ; break; - default : throw std::runtime_error( - "unexpected type : " + toml::stringize(data.at("something").type())); -} -``` - -The complete list of the `enum`s can be found in the section -[underlying types](#underlying-types). - -The `enum`s can be used as a parameter of `toml::value::is` function like the following. - -```cpp -toml::value v = /* ... */; -if(v.is(toml::value_t::Boolean)) // ... -``` - -## Casting value - -So far, `toml::get` is introduced, but if you don't need any type conversion, -`as_*` is simpler to use. - -```cpp -toml::value v = /* ... */; -if(v.is_integer() && v.as_integer() == 42) +const auto& answer = data.as_table().at("answer"); +if(answer.is_integer() && answer.as_integer(std::nothrow) == 42) { std::cout << "value is 42" << std::endl; } ``` -`as_*` functions internally checks the current contained type for safety and -throws `toml::type_error` if the contained value type is different (after toml11 -v2.4.0). If you already confirmed that the value has the type you will cast -into, you can skip the additional checking by passing `std::nothrow` object to it. - -```cpp -toml::value v = /* ... */; -if(v.is_integer() && v.as_integer(std::nothrow) == 42) // never fail -{ - std::cout << "value is 42" << std::endl; -} -``` +If `std::nothrow` is passed, the functions are marked as noexcept. The full list of the functions is below. @@ -681,9 +406,309 @@ class value { } // toml ``` -__NOTE__: `as_float` is marked as deprecated since v2.4.0 to make the function names consistent with snake case typenames. Please use `as_floating` instead. -## Visiting a toml::value + +## Checking value type + +You can check the type of a value by `is_xxx` function. + +```cpp +const toml::value v = /* ... */; +if(v.is_integer()) +{ + std::cout << "value is an integer" << std::endl; +} +``` + +The complete list of the functions is below. + +```cpp +namespace toml { +class value { + // ... + bool is_boolean() const noexcept; + bool is_integer() const noexcept; + bool is_floating() const noexcept; + bool is_string() const noexcept; + bool is_offset_datetime() const noexcept; + bool is_local_datetime() const noexcept; + bool is_local_date() const noexcept; + bool is_local_time() const noexcept; + bool is_array() const noexcept; + bool is_table() const noexcept; + bool is_uninitialized() const noexcept; + // ... +}; +} // toml +``` + +Also, you can get `enum class value_t` from `toml::value::type()`. + +```cpp +switch(data.at("something").type()) +{ + case toml::value_t::integer: /*do some stuff*/ ; break; + case toml::value_t::floating: /*do some stuff*/ ; break; + case toml::value_t::string : /*do some stuff*/ ; break; + default : throw std::runtime_error( + "unexpected type : " + toml::stringize(data.at("something").type())); +} +``` + +The complete list of the `enum`s can be found in the section +[underlying types](#underlying-types). + +The `enum`s can be used as a parameter of `toml::value::is` function like the following. + +```cpp +toml::value v = /* ... */; +if(v.is(toml::value_t::boolean)) // ... +``` + +**NOTE**: BREAKING CHANGES from v2.y.z: `(is|as)_float` has been removed. +Use `(is|as)_floating` instead. +See [Breaking Changes from v2](#breaking-changes-from-v2) for the complete list +of breaking changes. + +## More about conversion + +Since `toml::find` internally uses `toml::get`, all the following examples work +with both `toml::get` and `toml::find`. + +### Converting an array + +You can get any kind of `container` class from a `toml::array` +except for `map`-like classes. + +``` cpp +// # sample.toml +// numbers = [1,2,3] + +const auto numbers = toml::find(data, "numbers"); + +const auto vc = toml::get >(numbers); +const auto ls = toml::get >(numbers); +const auto dq = toml::get >(numbers); +const auto ar = toml::get>(numbers); +// if the size of data.at("numbers") is larger than that of std::array, +// it will throw toml::type_error because std::array is not resizable. +``` + +Surprisingly, you can convert `toml::array` into `std::pair` and `std::tuple`. + +```cpp +// numbers = [1,2,3] +const auto tp = toml::get>(numbers); +``` + +This functionality is helpful when you have a toml file like the following. + +```toml +array_of_arrays = [[1, 2, 3], ["foo", "bar", "baz"]] # toml allows this +``` + +What is the corresponding C++ type? +Obviously, it is a `std::pair` of `std::vector`s. + +```cpp +const auto array_of_arrays = toml::find(data, "array_of_arrays"); +const auto aofa = toml::get< + std::pair, std::vector> + >(array_of_arrays); +``` + +If you don't know the type of the elements, you can use `toml::array`, +which is a `std::vector` of `toml::value`, instead. + +```cpp +const auto a_of_a = toml::get(array_of_arrays); +const auto first = toml::get>(a_of_a.at(0)); +``` + +You can change the implementation of `toml::array` with `std::deque` or some +other array-like container. See [Customizing container](#customizing-container) +for detail. + +### Converting a table + +When all the values of the table have the same type, toml11 allows you to +convert a `toml::table` to a `map` that contains the convertible type. + +```toml +[tab] +key1 = "foo" # all the values are +key2 = "bar" # toml String +``` + +```cpp +const auto data = toml::parse("sample.toml"); +const auto tab = toml::find>(data, "tab"); +std::cout << tab["key1"] << std::endl; // foo +std::cout << tab["key2"] << std::endl; // bar +``` + +But since `toml::table` is just an alias of `std::unordered_map`, +normally you don't need to convert it because it has all the functionalities that +`std::unordered_map` has (e.g. `operator[]`, `count`, and `find`). In most cases +`toml::table` is sufficient. + +```cpp +toml::table tab = toml::get(data); +if(data.count("title") != 0) +{ + data["title"] = std::string("TOML example"); +} +``` + +You can change the implementation of `toml::table` with `std::map` or some +other map-like container. See [Customizing container](#customizing-container) +for detail. + +### Getting an array of tables + +An array of tables is just an array of tables. +You can get it in completely the same way as the other arrays and tables. + +```toml +# sample.toml +array_of_inline_tables = [{key = "value1"}, {key = "value2"}, {key = "value3"}] + +[[array_of_tables]] +key = "value4" +[[array_of_tables]] +key = "value5" +[[array_of_tables]] +key = "value6" +``` + +```cpp +const auto data = toml::parse("sample.toml"); +const auto aot1 = toml::find>(data, "array_of_inline_tables"); +const auto aot2 = toml::find>(data, "array_of_tables"); +``` + +### Cost of conversion + +Although conversion through `toml::(get|find)` is convenient, it has additional +copy-cost because it copies data contained in `toml::value` to the +user-specified type. Of course in some cases this overhead is not ignorable. + +```cpp +// the following code constructs a std::vector. +// it requires heap allocation for vector and element conversion. +const auto array = toml::find>(data, "foo"); +``` + +By passing the exact types, `toml::get` returns reference that has no overhead. + +``` cpp +const auto& tab = toml::find(data, "tab"); +const auto& numbers = toml::find(data, "numbers"); +``` + +Also, `as_xxx` are zero-overhead because they always return a reference. + +``` cpp +const auto& tab = toml::find(data, "tab" ).as_table(); +const auto& numbers = toml::find(data, "numbers").as_array(); +``` + +In this case you need to call `toml::get` each time you access to +the element of `toml::array` because `toml::array` is an array of `toml::value`. + +```cpp +const auto& num0 = toml::get(numbers.at(0)); +const auto& num1 = toml::get(numbers.at(1)); +const auto& num2 = toml::get(numbers.at(2)); +``` + +### Converting datetime and its variants + +TOML v0.5.0 has 4 different datetime objects, `local_date`, `local_time`, +`local_datetime`, and `offset_datetime`. + +Since `local_date`, `local_datetime`, and `offset_datetime` represent a time +point, you can convert them to `std::chrono::system_clock::time_point`. + +Contrary, `local_time` does not represents a time point because they lack a +date information, but it can be converted to `std::chrono::duration` that +represents a duration from the beginning of the day, `00:00:00.000`. + +```toml +date = 2018-12-23 +time = 12:30:00 +l_dt = 2018-12-23T12:30:00 +o_dt = 2018-12-23T12:30:00+09:30 +``` + +```cpp +const auto data = toml::parse("sample.toml"); + +const auto date = toml::get(data.at("date")); +const auto l_dt = toml::get(data.at("l_dt")); +const auto o_dt = toml::get(data.at("o_dt")); + +const auto time = toml::get(data.at("time")); // 12 * 60 + 30 min +``` + +toml11 defines its own datetime classes. +You can see the definitions in [toml/datetime.hpp](toml/datetime.hpp). + +## Getting with a fallback + +`toml::find_or` returns a default value if the value is not found or has a +different type. + +```cpp +const auto data = toml::parse("example.toml"); +const auto num = toml::find_or(data, "num", 42); +``` + +Also, `toml::get_or` returns a default value if `toml::get` failed. + +```cpp +toml::value v("foo"); // v contains String +const int value = toml::get_or(v, 42); // conversion fails. it returns 42. +``` + +These functions automatically deduce what type you want to get +from the default value you passed. + +To get a reference through this function, take care about the default value. + +```cpp +toml::value v("foo"); // v contains String +toml::integer& i = toml::get_or(v, 42); // does not work because binding `42` + // to `integer&` is invalid +toml::integer opt = 42; +toml::integer& i = toml::get_or(v, opt); // this works. +``` + +## Expecting conversion + +By using `toml::expect`, you will get your expected value or an error message +without throwing `toml::type_error`. + +```cpp +const auto value = toml::expect(data.at("title")); +if(value.is_ok()) { + std::cout << value.unwrap() << std::endl; +} else { + std::cout << value.unwrap_err() << std::endl; +} +``` + +Also, you can pass a function object to modify the expected value. + +```cpp +const auto value = toml::expect(data.at("number")) + .map(// function that receives expected type (here, int) + [](const int number) -> double { + return number * 1.5 + 1.0; + }).unwrap_or(/*default value =*/ 3.14); +``` + +## Visiting toml::value toml11 provides `toml::visit` to apply a function to `toml::value` in the same way as `std::variant`. @@ -699,6 +724,18 @@ The function object that would be passed to `toml::visit` must be able to recieve all the possible TOML types. Also, the result types should be the same each other. +## Constructing a toml::value + +TODO + +## Preserving Comments + +TODO + +## Customizing container + +TODO + ## TOML literal toml11 supports `"..."_toml` literal. @@ -730,7 +767,7 @@ inline namespace literals { inline namespace toml_literals { -toml::value operator""_toml(const char* str, std::size_t len); +toml::value operator"" _toml(const char* str, std::size_t len); } // toml_literals } // literals @@ -903,18 +940,6 @@ toml::value v(f); Any type that can be converted to `toml::value`, e.g. `toml::table`, `toml::array`, is okay to return from `into_toml`. -## Invalid UTF-8 codepoints - -toml11 throws `syntax_error` if a value of an escape sequence -representing unicode character is not a valid UTF-8 codepoint. - -```console - what(): [error] toml::read_utf8_codepoint: input codepoint is too large. - --> utf8.toml - 1 | exceeds_unicode = "\U0011FFFF example" - | ^--------- should be in [0x00..0x10FFFF] -``` - ## Formatting user-defined error messages When you encounter an error after you read the toml value, you may want to @@ -968,56 +993,15 @@ you will get an error message like this. | ~~ maximum number here ``` -## Getting comments +### Obtaining location information -Since toml11 keeps a file data until all the values are destructed, you can -also extract a comment related to a value by calling `toml::value::comment()`. +`source_location` -If there is a comment just after a value (within the same line), you can get -the specific comment by `toml::value::comment_inline()`. - -If there are comments just before a value (without any newline between them), -you can get the comments by `toml::value::comment_before()`. - -`toml::value::comment()` returns the results of both functions after -concatenating them. - -```toml -a = 42 # comment for a. - -# comment for b. -# this is also a comment for b. -b = "foo" - -c = [ # comment for c. - 3.14, # this is not a comment for c, but for 3.14. -] # this is also a comment for c. -``` - -```cpp -// "# comment for a." -const std::string com1 = toml::find(data, "a").comment(); - -// "# comment for b." -const std::string com2 = toml::find(data, "b").comment(); - -// "# comment for c.\n# this is also a comment for c." -const std::string com3 = toml::find(data, "c").comment(); - -// "# this is not a comment for c, but for 3.14." -const std::string com3 = toml::find(data, "c").front().comment(); -``` - -Note that once a data in a value is modified, the related file region -information would be deleted. Thus after modifying a data, you cannot find any -comments. - -Also note that currently it does not support any way to set a comment to a value. -And currently, serializer does not take comments into account. +TODO ## Serializing TOML data -toml11 (after v2.1.0) enables you to serialize data into toml format. +toml11 enables you to serialize data into toml format. ```cpp const auto data = toml::table{{"foo", 42}, {"bar", "baz"}}; @@ -1111,22 +1095,28 @@ third arguments to set them. By default, the witdh is 80 and the precision is const auto serial = toml::format(data, /*width = */ 0, /*prec = */ 17); ``` +When you pass a comment-preserving-value, the comment will also be serialized. + ## Underlying types The toml types (can be used as `toml::*` in this library) and corresponding `enum` names are listed in the table below. -| toml::type | underlying c++ type | enum | -| -------------- | -------------------------------------------- | ------------------------------- | -| Boolean | `bool` | `toml::value_t::Boolean` | -| Integer | `std::int64_t` | `toml::value_t::Integer` | -| Float | `double` | `toml::value_t::Float` | -| String | `toml::string` | `toml::value_t::String` | -| LocalDate | `toml::local_date` | `toml::value_t::LocalDate` | -| LocalTime | `toml::local_time` | `toml::value_t::LocalTime` | -| LocalDatetime | `toml::local_datetime` | `toml::value_t::LocalDatetime` | -| OffsetDatetime | `toml::offset_datetime` | `toml::value_t::OffsetDatetime` | -| Array | `std::vector` | `toml::value_t::Array` | -| Table | `std::unordered_map` | `toml::value_t::Table` | +| TOML type | underlying c++ type | enum class | +| -------------- | ---------------------------------- | -------------------------------- | +| Boolean | `bool` | `toml::value_t::boolean` | +| Integer | `std::int64_t` | `toml::value_t::integer` | +| Float | `double` | `toml::value_t::floating` | +| String | `toml::string` | `toml::value_t::string` | +| LocalDate | `toml::local_date` | `toml::value_t::local_date` | +| LocalTime | `toml::local_time` | `toml::value_t::local_time` | +| LocalDatetime | `toml::local_datetime` | `toml::value_t::local_datetime` | +| OffsetDatetime | `toml::offset_datetime` | `toml::value_t::offset_datetime` | +| Array | `array-like` | `toml::value_t::array` | +| Table | `map-like` | `toml::value_t::table` | + +`array-like` and `map-like` are the STL containers that works like a `std::vector` and +`std::unordered_map`, respectively. By default, `std::vector` and `std::unordered_map` +are used. See [Customizing containers](#customizing-containers) for detail. `toml::string` is effectively the same as `std::string` but has an additional flag that represents a kind of a string, `string_t::basic` and `string_t::literal`. @@ -1139,6 +1129,27 @@ not capable of representing a Local Time independent from a specific day. It is recommended to get `Datetime`s as `std::chrono` classes through `toml::get`. +## Breaking Changes from v2 + +Although toml11 is relatively new library (it's three years old now), it had +some confusing and inconvenient user-interfaces because of historical reasons. + +Between v2 and v3, those interfaces are rearranged. + +- `toml::parse` now returns a `toml::value`, not `toml::table`. +- `toml::value` is now an alias of `toml::basic_value`. + See [Customizing containers](#customizing-containers) for detail. +- The elements of `toml::value_t` are renamed as `snake_case`. +- Supports for the CamelCaseNames are dropped. +- `(is|as)_float` has been removed to make the function names consistent with others. + Since `float` is a keyword, toml11 named a float type as `toml::floating`. + Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. + So `(is|as)_floating` is introduced and `is_float` has been removed. +- Interface around comments. +- An old `from_toml` has been removed + +Such a big change will not happen in the coming years. + ## Running Tests To run test codes, you need to clone toml-lang/toml repository under `build/` directory From af19dfe0321c84c6a32b35f428b8d175701a3444 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 20:19:51 +0900 Subject: [PATCH 061/162] fix: conversion between different basic_values --- toml/value.hpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 578cdb2..5597970 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -256,6 +256,10 @@ class basic_value using region_base = detail::region_base; + template class T, + template class A> + friend class basic_value; + public: using comment_type = Comment; @@ -368,7 +372,7 @@ class basic_value template class T, template class A> basic_value(const basic_value& v) - : type_(v.type()), region_info_(v.region_info_), comments_(v.comments_) + : type_(v.type()), region_info_(v.region_info_), comments_(v.comments()) { switch(v.type()) { @@ -382,13 +386,15 @@ class basic_value case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; case value_t::array : { - array_type tmp(v.array_.begin(), v.array_.end()); + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); assigner(array_, std::move(tmp)); break; } case value_t::table : { - table_type tmp(v.table_.begin(), v.table_.end()); + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); assigner(table_, std::move(tmp)); break; } @@ -401,8 +407,8 @@ class basic_value basic_value& operator=(const basic_value& v) { this->region_info_ = v.region_info_; - this->comments_ = v.comments_; - this->type_ = v.type_; + this->comments_ = v.comments(); + this->type_ = v.type(); switch(v.type()) { case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; @@ -415,18 +421,21 @@ class basic_value case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; case value_t::array : { - array_type tmp(v.array_.begin(), v.array_.end()); + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); assigner(array_, std::move(tmp)); break; } case value_t::table : { - table_type tmp(v.table_.begin(), v.table_.end()); + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); assigner(table_, std::move(tmp)); break; } default: break; } + return *this; } // boolean ============================================================== From cc4a9c8d5d1908cec10271a43d0952ac2099a494 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 20:20:14 +0900 Subject: [PATCH 062/162] fix: consider identity conversion in SFINAE --- toml/get.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/toml/get.hpp b/toml/get.hpp index bbc9a09..1859bbb 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -69,7 +69,9 @@ get(basic_value&& v) template class M, template class V> -inline detail::enable_if_t::value, T> +inline detail::enable_if_t, + detail::negation>> + >::value, T> get(const basic_value& v) { return T(v); From 8665272babceac3f6bc064281bb300823825a92d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 20:25:19 +0900 Subject: [PATCH 063/162] test: add test for custom basic_value type --- tests/test_parse_file.cpp | 175 +++++++++++++++++++++++++++++++++++++- 1 file changed, 174 insertions(+), 1 deletion(-) diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index 0e974b7..ef3cf84 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -8,7 +8,8 @@ #include #include #include - +#include +#include BOOST_AUTO_TEST_CASE(test_example) { @@ -693,3 +694,175 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); } } + +BOOST_AUTO_TEST_CASE(test_example_preserve_comment) +{ + const auto data = toml::parse("toml/tests/example.toml"); + + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_CHECK_EQUAL(alpha.comments().at(0), + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); + BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); + BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); + BOOST_CHECK_EQUAL(toml::find(beta, "country"), + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + "Hammer"); + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + 738594937); + + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + "Nail"); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + 284758393); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) +{ + const auto data = toml::parse("toml/tests/example.toml"); + + static_assert(std::is_same::type> + >::value, ""); + static_assert(std::is_same::type> + >::value, ""); + + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_CHECK_EQUAL(alpha.comments().at(0), + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); + BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); + BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); + BOOST_CHECK_EQUAL(toml::find(beta, "country"), + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + "Hammer"); + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + 738594937); + + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + "Nail"); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + 284758393); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + "gray"); + } +} From fec4e1db9a25862429b314a9b7097ec053900387 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 15 Jun 2019 20:34:20 +0900 Subject: [PATCH 064/162] doc(WIP): add source_location to README --- README.md | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7163a8d..c1d50ec 100644 --- a/README.md +++ b/README.md @@ -995,9 +995,34 @@ you will get an error message like this. ### Obtaining location information -`source_location` +You can get `source_location` by calling `toml::value::location()`. -TODO +```cpp +const toml::value v = /**/; +const toml::source_location sl = v.location(); +``` + +You can use it to format your own error message. + +```cpp +class source_location { + public: + +// +-- line() +-- region of interest (region() == 9) +// v .---+---. +// 12 | value = "foo bar" +// ^ +// +-- column() + + std::uint_least32_t line() const noexcept; + std::uint_least32_t column() const noexcept; + std::uint_least32_t region() const noexcept; + + std::string const& file_name() const noexcept; + std::string const& line_str() const noexcept; // the line itself +// ... +}; +``` ## Serializing TOML data From d9ad0e4b92eb7c3e14c00b1db29568bfc3b06ed2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sun, 16 Jun 2019 23:44:54 +0900 Subject: [PATCH 065/162] doc: add source_location to README --- README.md | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7163a8d..fce9b9d 100644 --- a/README.md +++ b/README.md @@ -995,9 +995,28 @@ you will get an error message like this. ### Obtaining location information -`source_location` +You can also format error messages in your own way by using `source_location`. -TODO +```cpp +struct source_location +{ + std::uint_least32_t line() const noexcept; + std::uint_least32_t column() const noexcept; + std::uint_least32_t region() const noexcept; + std::string const& file_name() const noexcept; + std::string const& line_str() const noexcept; +}; +// +-- line() +--- length of the region (here, region() == 9) +// v .---+---. +// 12 | value = "foo bar" +// ^-------- column() points here +``` + +You can get this by +```cpp +const toml::value v = /*...*/; +const toml::source_location loc = v.location(); +``` ## Serializing TOML data @@ -1096,6 +1115,7 @@ const auto serial = toml::format(data, /*width = */ 0, /*prec = */ 17); ``` When you pass a comment-preserving-value, the comment will also be serialized. +An array or a table containing a value that has a comment would not be inlined. ## Underlying types @@ -1127,7 +1147,7 @@ that points to internal `std::string` by using `toml::get()` for co Because `std::chrono::system_clock::time_point` is a __time point__, not capable of representing a Local Time independent from a specific day. -It is recommended to get `Datetime`s as `std::chrono` classes through `toml::get`. +It is recommended to get `datetime`s as `std::chrono` classes through `toml::get`. ## Breaking Changes from v2 @@ -1138,14 +1158,16 @@ Between v2 and v3, those interfaces are rearranged. - `toml::parse` now returns a `toml::value`, not `toml::table`. - `toml::value` is now an alias of `toml::basic_value`. - See [Customizing containers](#customizing-containers) for detail. + - See [Customizing containers](#customizing-containers) for detail. - The elements of `toml::value_t` are renamed as `snake_case`. - Supports for the CamelCaseNames are dropped. - `(is|as)_float` has been removed to make the function names consistent with others. Since `float` is a keyword, toml11 named a float type as `toml::floating`. Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. So `(is|as)_floating` is introduced and `is_float` has been removed. +- `toml::find` for `toml::table` has been dropped. Use `toml::value` version instead. - Interface around comments. + - See [Preserving Comments](#preserving-comments) for detail. - An old `from_toml` has been removed Such a big change will not happen in the coming years. From 12ef0f6287b930abeca710164ee5cad9ff01fb74 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 00:29:43 +0900 Subject: [PATCH 066/162] doc: add containers and comments to README --- README.md | 108 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 99 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fce9b9d..a054a55 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ int main() - [Visiting a toml::value](#visiting-a-tomlvalue) - [Constructing a toml::value](#constructing-a-tomlvalue) - [Preserving Comments](#preserving-comments) -- [Customizing container](#customizing-container) +- [Customizing containers](#customizing-containers) - [TOML literal](#toml-literal) - [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) @@ -323,9 +323,9 @@ contain one of the following types. - `toml::local_datetime` - `toml::offset_datetime` - `toml::array` (by default, `std::vector`) - - It depends. See [customize toml::value](#customize-toml-value) for detail. + - It depends. See [customizing containers](#customizing-containers) for detail. - `toml::table` (by default, `std::unordered_map`) - - It depends. See [customize toml::value](#customize-toml-value) for detail. + - It depends. See [customizing containers](#customizing-containers) for detail. To get a value inside, you can use `toml::get()`. The usage is the same as `toml::find` (actually, `toml::find` internally uses `toml::get`). @@ -526,7 +526,7 @@ const auto first = toml::get>(a_of_a.at(0)); ``` You can change the implementation of `toml::array` with `std::deque` or some -other array-like container. See [Customizing container](#customizing-container) +other array-like container. See [Customizing containers](#customizing-containers) for detail. ### Converting a table @@ -561,7 +561,7 @@ if(data.count("title") != 0) ``` You can change the implementation of `toml::table` with `std::map` or some -other map-like container. See [Customizing container](#customizing-container) +other map-like container. See [Customizing containers](#customizing-containers) for detail. ### Getting an array of tables @@ -728,13 +728,103 @@ each other. TODO -## Preserving Comments +## Preserving comments -TODO +After toml11 v3, you can choose whether comments are preserved or not. -## Customizing container +```cpp +const auto data1 = toml::parse("example.toml"); +const auto data2 = toml::parse("example.toml"); +``` -TODO +Comments related to a value can be obtained by `toml::value::comments()`. +The return value has the same interface as `std::vector`. + +```cpp +const auto& com = v.comments(); +for(const auto& c : com) +{ + std::cout << c << std::endl; +} +``` + +Comments just before and just after a value are kept in a value. + +```toml +# this is a comment for v1. +v1 = "foo" + +v2 = "bar" # this is a comment for v2. + +# this comment is not related to any value +# because there are empty lines between v3. +# this comment will be ignored even if you set `preserve_comments`. + +# this is a comment for v3 +# this is also a comment for v3 +v3 = "baz" # ditto. +``` + +Each comment line becomes one element of a `std::vector`. +Hash signs will be removed, but spaces after hash sign will not be removed. + +```cpp +v1.comments().at(0) == " this is a comment for v1."s; + +v2.comments().at(1) == " this is a comment for v1."s; + +v3.comments().at(0) == " this is a comment for v3."s; +v3.comments().at(1) == " this is also a comment for v3."s; +v3.comments().at(2) == " ditto."s; +``` + +Note that a comment just after an opening brace of an array will not be a +comment for the array. + +```toml +# this is a comment for a. +a = [ # this is not a comment for a. this will be ignored. + 1, 2, 3, + # this is a comment for `42`. + 42, # this is also a comment for `42`. + 5 +] # this is a comment for a. +``` + +You can also append comments. The interfaces are the same as `std::vector`. + +```cpp +v.comments().push_back(" add new comment."); +``` + +When `toml::discard_comments` is chosen, `value::comments()` will always be kept +empty. All the modification on comments would be ignored. + +The comments will also be serialized. If comments exist, those comments will be +added just before the values. + +## Customizing containers + +`toml::basic_value` has 3 template arguments. + +```cpp +template class Table = std::unordered_map, + template class Array = std::vector> +class basic_value; +``` + +This enables you to change the containers used inside. E.g. you can use +`std::map` to contain a table object instead of `std::unordered_map`. +And also can use `std::deque` as a array object instead of `std::vector`. + +You can set these parameters while calling `toml::parse` function. + +```cpp +const auto data = toml::parse< + toml::preserve_comments, std::map, std::deque + >("example.toml"); +``` ## TOML literal From 10f410a02c9654f564770e70e701a0f69922e7ae Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 00:48:06 +0900 Subject: [PATCH 067/162] doc: add some notes and comments to README --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a054a55..d2908f7 100644 --- a/README.md +++ b/README.md @@ -305,6 +305,8 @@ The above code works with the following toml file. ```toml "physical.color" = "orange" +# equivalent to {"physical.color": "orange"}, +# NOT {"physical": {"color": "orange"}}. ``` ## Casting a toml value @@ -748,24 +750,26 @@ for(const auto& c : com) } ``` -Comments just before and just after a value are kept in a value. +Comments just before and just after (within the same line) a value are kept in a value. ```toml # this is a comment for v1. v1 = "foo" v2 = "bar" # this is a comment for v2. +# Note that this comment is NOT a comment for v2. # this comment is not related to any value # because there are empty lines between v3. # this comment will be ignored even if you set `preserve_comments`. # this is a comment for v3 -# this is also a comment for v3 +# this is also a comment for v3. v3 = "baz" # ditto. ``` Each comment line becomes one element of a `std::vector`. + Hash signs will be removed, but spaces after hash sign will not be removed. ```cpp @@ -805,7 +809,7 @@ added just before the values. ## Customizing containers -`toml::basic_value` has 3 template arguments. +Actually, `toml::basic_value` has 3 template arguments. ```cpp template`. - See [Customizing containers](#customizing-containers) for detail. - The elements of `toml::value_t` are renamed as `snake_case`. + - See [Underlying types](#underlying-types) for detail. - Supports for the CamelCaseNames are dropped. + - See [Underlying types](#underlying-types) for detail. - `(is|as)_float` has been removed to make the function names consistent with others. Since `float` is a keyword, toml11 named a float type as `toml::floating`. Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. So `(is|as)_floating` is introduced and `is_float` has been removed. + - See [Casting a toml::value](#casting-a-tomlvalue) and [Checking value type](#checking-value-type) for detail. - `toml::find` for `toml::table` has been dropped. Use `toml::value` version instead. + - See [Finding a toml::value](#finding-a-tomlvalue) for detail. - Interface around comments. - See [Preserving Comments](#preserving-comments) for detail. - An old `from_toml` has been removed From 0604cf813a88fb0db894b6b3f76ca6db45d171a8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 01:24:32 +0900 Subject: [PATCH 068/162] feat: :boom: remove toml::find for tables --- toml/get.hpp | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index bbc9a09..fbecd60 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -421,48 +421,6 @@ T get(const basic_value& v) // ============================================================================ // find and get -// for toml::table. -template -detail::enable_if_t, - detail::is_basic_value>::value, - decltype(::toml::get(std::declval()))> -find(Table& tab, const toml::key& ky, std::string tn = "unknown table") -{ - if(tab.count(ky) == 0) - { - throw std::out_of_range(concat_to_string( - "[error] key \"", ky, "\" not found in ", tn)); - } - return ::toml::get(tab.at(ky)); -} -template -detail::enable_if_t, - detail::is_basic_value>::value, - decltype(::toml::get(std::declval()))> -find(Table const& tab, const toml::key& ky, std::string tn = "unknown table") -{ - if(tab.count(ky) == 0) - { - throw std::out_of_range(concat_to_string( - "[error] key \"", ky, "\" not found in ", tn)); - } - return ::toml::get(tab.at(ky)); -} -template -detail::enable_if_t, - detail::is_basic_value>::value, - decltype(::toml::get(std::declval()))> -find(typename std::remove_reference
&& tab, const toml::key& ky, - std::string tn = "unknown table") -{ - if(tab.count(ky) == 0) - { - throw std::out_of_range(concat_to_string( - "[error] key \"", ky, "\" not found in ", tn)); - } - return ::toml::get(std::move(tab.at(ky))); -} - // ---------------------------------------------------------------------------- // these overloads do not require to set T. and returns value itself. template Date: Mon, 17 Jun 2019 01:26:05 +0900 Subject: [PATCH 069/162] feat: :boom: remove toml::find_or for toml::table --- toml/get.hpp | 101 --------------------------------------------------- 1 file changed, 101 deletions(-) diff --git a/toml/get.hpp b/toml/get.hpp index fbecd60..3af7ea8 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -825,107 +825,6 @@ find_or(const basic_value& v, const toml::key& ky, T&& opt) return get_or(tab.at(ky), std::forward(opt)); } -// =========================================================================== -// find_or(table, key, opt) - -// --------------------------------------------------------------------------- -// exact types (return type can be a reference) -template -detail::enable_if_t, detail::is_basic_value, - detail::is_exact_toml_type - >::value, T> const& -find_or(const Table& tab, const key& ky, const T& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(tab.at(ky), opt); -} - -template -detail::enable_if_t, detail::is_basic_value, - detail::is_exact_toml_type - >::value, T>& -find_or(Table& tab, const key& ky, T& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(tab[ky], opt); -} - -template -detail::enable_if_t, detail::is_basic_value, - detail::is_exact_toml_type - >::value, T>&& -find_or(typename std::remove_reference
::type&& tab, const key& ky, T&& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(std::move(tab[ky]), std::forward(opt)); -} - -// --------------------------------------------------------------------------- -// std::string (return type can be a reference) -template -detail::enable_if_t, detail::is_basic_value, - std::is_same - >::value, std::string> const& -find_or(const Table& tab, const key& ky, const T& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(tab.at(ky), opt); -} -template -detail::enable_if_t, detail::is_basic_value, - std::is_same - >::value, std::string>& -find_or(Table& tab, const key& ky, T& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(tab[ky], opt); -} -template -detail::enable_if_t, detail::is_basic_value, - std::is_same - >::value, std::string> -find_or(Table&& tab, const key& ky, T&& opt) -{ - if(tab.count(ky) == 0) {return std::forward(opt);} - return get_or(std::move(tab[ky]), std::forward(opt)); -} - -// --------------------------------------------------------------------------- -// string literal (deduced as std::string) -template -detail::enable_if_t, - detail::is_basic_value, - detail::is_string_literal::type> - >::value, std::string> -find_or(const Table& tab, const key& ky, T&& opt) -{ - if(tab.count(ky) == 0) {return std::string(opt);} - return get_or(tab.at(ky), std::forward(opt)); -} - -// --------------------------------------------------------------------------- -// others (require type conversion and return type cannot be lvalue reference) -template -detail::enable_if_t, - detail::is_basic_value, - detail::negation>, - detail::negation>, - detail::negation::type>> - >::value, T> -find_or(const Table& tab, const key& ky, T&& opt) -{ - if(tab.count(ky) == 0) {return opt;} - return get_or(tab.at(ky), std::forward(opt)); -} - // ============================================================================ // expect From b3300fad2a06112d1f9ca5603266b97d0c6d80ab Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 12:13:59 +0900 Subject: [PATCH 070/162] fix: move element of map in toml::find(val&&) --- toml/get.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/get.hpp b/toml/get.hpp index bc9f43f..2314f32 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -465,7 +465,7 @@ basic_value&& find(basic_value&& v, const key& ky) {std::addressof(detail::get_region(v)), "in this table"} })); } - return tab.at(ky); + return std::move(tab.at(ky)); } // ---------------------------------------------------------------------------- From f36b39c04f4f5caf2c17e625479ebfac087b20bb Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 20:33:38 +0900 Subject: [PATCH 071/162] fix: consider comments while comparing values --- toml/value.hpp | 54 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 5597970..48e6814 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1339,7 +1339,9 @@ template class T, template clas inline bool operator==(const basic_value& lhs, const basic_value& rhs) { - if(lhs.type() != rhs.type()){return false;} + if(lhs.type() != rhs.type()) {return false;} + if(lhs.comments() != rhs.comments()) {return false;} + switch(lhs.type()) { case value_t::boolean : @@ -1395,46 +1397,72 @@ operator<(const basic_value& lhs, const basic_value& rhs) { case value_t::boolean : { - return lhs.as_boolean() < rhs.as_boolean(); + return lhs.as_boolean() < rhs.as_boolean() || + (lhs.as_boolean() == rhs.as_boolean() && + lhs.comments() < rhs.comments()); } case value_t::integer : { - return lhs.as_integer() < rhs.as_integer(); + return lhs.as_integer() < rhs.as_integer() || + (lhs.as_integer() == rhs.as_integer() && + lhs.comments() < rhs.comments()); } case value_t::floating : { - return lhs.as_floating() < rhs.as_floating(); + return lhs.as_floating() < rhs.as_floating() || + (lhs.as_floating() == rhs.as_floating() && + lhs.comments() < rhs.comments()); } case value_t::string : { - return lhs.as_string() < rhs.as_string(); + return lhs.as_string() < rhs.as_string() || + (lhs.as_string() == rhs.as_string() && + lhs.comments() < rhs.comments()); } case value_t::offset_datetime: { - return lhs.as_offset_datetime() < rhs.as_offset_datetime(); + return lhs.as_offset_datetime() < rhs.as_offset_datetime() || + (lhs.as_offset_datetime() == rhs.as_offset_datetime() && + lhs.comments() < rhs.comments()); } case value_t::local_datetime: { - return lhs.as_local_datetime() < rhs.as_local_datetime(); + return lhs.as_local_datetime() < rhs.as_local_datetime() || + (lhs.as_local_datetime() == rhs.as_local_datetime() && + lhs.comments() < rhs.comments()); } case value_t::local_date: { - return lhs.as_local_date() < rhs.as_local_date(); + return lhs.as_local_date() < rhs.as_local_date() || + (lhs.as_local_date() == rhs.as_local_date() && + lhs.comments() < rhs.comments()); } case value_t::local_time: { - return lhs.as_local_time() < rhs.as_local_time(); + return lhs.as_local_time() < rhs.as_local_time() || + (lhs.as_local_time() == rhs.as_local_time() && + lhs.comments() < rhs.comments()); } case value_t::array : { - return lhs.as_array() < rhs.as_array(); + return lhs.as_array() < rhs.as_array() || + (lhs.as_array() == rhs.as_array() && + lhs.comments() < rhs.comments()); } case value_t::table : { - return lhs.as_table() < rhs.as_table(); + return lhs.as_table() < rhs.as_table() || + (lhs.as_table() == rhs.as_table() && + lhs.comments() < rhs.comments()); + } + case value_t::empty : + { + return lhs.comments() < rhs.comments(); + } + default: + { + return lhs.comments() < rhs.comments(); } - case value_t::empty : {return false;} - default: {return false;} } } From 57b5545ba275c50a60c08ad1abf16a11f6139bf8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 20:34:13 +0900 Subject: [PATCH 072/162] fix: add _type suffix to value::xxx_type --- toml/value.hpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 48e6814..d1962f7 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -262,19 +262,19 @@ class basic_value public: - using comment_type = Comment; - using key_type = ::toml::key; - using value_type = basic_value; - using boolean_type = ::toml::boolean; - using integer_type = ::toml::integer; - using floating_type = ::toml::floating; - using string_type = ::toml::string; - using local_time = ::toml::local_time; - using local_date = ::toml::local_date; - using local_datetime = ::toml::local_datetime; - using offset_datetime = ::toml::offset_datetime; - using array_type = Array; - using table_type = Table; + using comment_type = Comment; + using key_type = ::toml::key; + using value_type = basic_value; + using boolean_type = ::toml::boolean; + using integer_type = ::toml::integer; + using floating_type = ::toml::floating; + using string_type = ::toml::string; + using local_time_type = ::toml::local_time; + using local_date_type = ::toml::local_date; + using local_datetime_type = ::toml::local_datetime; + using offset_datetime_type = ::toml::offset_datetime; + using array_type = Array; + using table_type = Table; public: From 7eac3a30289d6b2a01a01055607babbb212e51d2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 20:34:42 +0900 Subject: [PATCH 073/162] feat: support serialization of basic_value --- toml/serializer.hpp | 110 +++++++++++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 43 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index bd6d668..b458aeb 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -10,8 +10,25 @@ namespace toml { +template class Table, + template class Array> struct serializer { + using value_type = basic_value; + 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 = 80, const int float_prec = std::numeric_limits::max_digits10, const bool can_be_inlined = false, @@ -21,15 +38,15 @@ struct serializer {} ~serializer() = default; - std::string operator()(const toml::boolean& b) const + std::string operator()(const boolean_type& b) const { return b ? "true" : "false"; } - std::string operator()(const integer i) const + std::string operator()(const integer_type i) const { return std::to_string(i); } - std::string operator()(const toml::floating f) const + std::string operator()(const floating_type f) const { const auto fmt = "%.*g"; const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f); @@ -68,7 +85,7 @@ struct serializer } return token; } - std::string operator()(const string& s) const + std::string operator()(const string_type& s) const { if(s.kind == string_t::basic) { @@ -130,32 +147,32 @@ struct serializer } } - std::string operator()(const local_date& d) const + std::string operator()(const local_date_type& d) const { std::ostringstream oss; oss << d; return oss.str(); } - std::string operator()(const local_time& t) const + std::string operator()(const local_time_type& t) const { std::ostringstream oss; oss << t; return oss.str(); } - std::string operator()(const local_datetime& dt) const + std::string operator()(const local_datetime_type& dt) const { std::ostringstream oss; oss << dt; return oss.str(); } - std::string operator()(const offset_datetime& odt) const + std::string operator()(const offset_datetime_type& odt) const { std::ostringstream oss; oss << odt; return oss.str(); } - std::string operator()(const array& v) const + std::string operator()(const array_type& v) const { if(!v.empty() && v.front().is_table())// v is an array of tables { @@ -173,8 +190,7 @@ struct serializer token += "[\n"; for(const auto& item : v) { - const auto t = - this->make_inline_table(item.cast()); + 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()) @@ -199,7 +215,7 @@ struct serializer token += "[["; token += this->serialize_dotted_key(keys_); token += "]]\n"; - token += this->make_multiline_table(item.cast()); + token += this->make_multiline_table(item.as_table()); } return token; } @@ -258,7 +274,8 @@ struct serializer return token; } - std::string operator()(const table& v) const + // templatize for any table-like container + std::string operator()(const table_type& v) const { if(this->can_be_inlined_) { @@ -369,7 +386,7 @@ struct serializer return retval; } - std::string make_inline_array(const array& v) const + std::string make_inline_array(const array_type& v) const { std::string token; token += '['; @@ -384,7 +401,7 @@ struct serializer return token; } - std::string make_inline_table(const table& v) const + std::string make_inline_table(const table_type& v) const { assert(this->can_be_inlined_); std::string token; @@ -403,7 +420,7 @@ struct serializer return token; } - std::string make_multiline_table(const table& v) const + std::string make_multiline_table(const table_type& v) const { std::string token; @@ -465,7 +482,7 @@ struct serializer return token; } - bool is_array_of_tables(const value& v) const + bool is_array_of_tables(const value_type& v) const { if(!v.is_array()) {return false;} const auto& a = v.as_array(); @@ -480,45 +497,52 @@ struct serializer std::vector keys_; }; -inline std::string -format(const value& v, std::size_t w = 80, +template class M, template class V> +std::string +format(const basic_value& v, std::size_t w = 80, int fprec = std::numeric_limits::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. so pass false. otherwise, true. - return visit(serializer(w, fprec, (!v.is_table()) || force_inline), v); -} -inline std::string -format(const table& t, std::size_t w = 80, - int fprec = std::numeric_limits::max_digits10, - bool force_inline = false) -{ - return serializer(w, fprec, force_inline)(t); + // 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(w, fprec, false), v); + return oss.str(); + } + return visit(serializer(w, fprec, force_inline), v); } -template +template class M, template class V> std::basic_ostream& -operator<<(std::basic_ostream& os, const value& v) +operator<<(std::basic_ostream& os, const basic_value& v) { // get status of std::setw(). const std::size_t w = os.width(); const int fprec = 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(w, fprec, false), v); - return os; -} -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const table& v) -{ - // get status of std::setw(). - const std::size_t w = os.width(); - const int fprec = os.precision(); - os.width(0); - // the root object can't be an inline table. so pass `false`. - os << serializer(w, fprec, false)(v); + os << visit(serializer(w, fprec, false), v); return os; } From d10c0725fd46ff1d32b4906f0600c985b27640af Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:12:20 +0900 Subject: [PATCH 074/162] fix: consider closing bracket when collect comments table = {key = "value"} # comment. a value named "table" ({key = "value"}) has the above comment. but a value named "key" ("value") does not have any comment. --- toml/region.hpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 2f5b0b9..987238b 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -309,7 +309,6 @@ struct region final : public region_base { 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(); @@ -372,10 +371,18 @@ struct region final : public region_base std::find(this->last(), this->line_end(), '#'); if(comment_found != this->line_end()) // '#' found { - // 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)); + // 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 == ']'; + })) + { + // 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; From 6399d44e3bcd6e30fac5426d628a24b08a16a230 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:13:58 +0900 Subject: [PATCH 075/162] fix: consider comments while serialization --- toml/serializer.hpp | 142 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 19 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index b458aeb..b3e3637 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -177,7 +177,14 @@ struct serializer 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, we need `table.key = [...]`. + // but if it can be inlined, + // ``` + // table.key = [ + // {...}, + // # comment + // {...}, + // ] + // ``` if(this->can_be_inlined_) { std::string token; @@ -186,32 +193,52 @@ struct serializer token += this->serialize_key(keys_.back()); token += " = "; } - bool width_exceeds = false; + 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()) { - width_exceeds = true; + failed = true; break; } token += t; token += ",\n"; } - if(!width_exceeds) + if(!failed) { token += "]\n"; return token; } - // if width_exceeds, serialize it as [[array.of.tables]]. + // 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"; @@ -224,7 +251,9 @@ struct serializer return std::string("[]"); } - // not an array of tables. normal array. first, try to make it inline. + // 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_ && @@ -234,16 +263,54 @@ struct serializer } } - // if the length exceeds this->width_, print multiline array + // 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) { - auto next_elem = toml::visit(*this, item); - // newline between array-value and comma is not allowed - if(next_elem.back() == '\n'){next_elem.pop_back();} + 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; @@ -251,12 +318,13 @@ struct serializer } else if(current_line.empty()) { - // the next elem cannot be within the width. + // if current line was empty, force put the next_elem because + // next_elem is not splittable token += next_elem; token += ",\n"; - // keep current line empty + // current_line is kept empty } - else // current_line has some tokens and it exceeds width + else // reset current_line { assert(current_line.back() == ','); token += current_line; @@ -265,11 +333,6 @@ struct serializer current_line += ','; } } - if(!current_line.empty()) - { - if(current_line.back() != '\n') {current_line += '\n';} - token += current_line; - } token += "]\n"; return token; } @@ -277,7 +340,9 @@ struct serializer // templatize for any table-like container std::string operator()(const table_type& v) const { - if(this->can_be_inlined_) + // 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()) @@ -386,8 +451,27 @@ struct serializer 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; @@ -403,6 +487,7 @@ struct serializer std::string make_inline_table(const table_type& v) const { + assert(!has_comment_inside(v)); assert(this->can_be_inlined_); std::string token; token += '{'; @@ -433,6 +518,15 @@ struct serializer 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; @@ -477,6 +571,16 @@ struct serializer // 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; From bf4eae0b76e93c3288b0953c34fb41775c86c3c1 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:14:26 +0900 Subject: [PATCH 076/162] test: drop test for find_or(table) --- tests/test_get_related_func.cpp | 101 +------------------------------- 1 file changed, 2 insertions(+), 99 deletions(-) diff --git a/tests/test_get_related_func.cpp b/tests/test_get_related_func.cpp index e6e448c..32b9ab8 100644 --- a/tests/test_get_related_func.cpp +++ b/tests/test_get_related_func.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(test_find_for_value) { thrown = true; } - BOOST_CHECK(thrown); + BOOST_CHECK(thrown); } { @@ -78,37 +78,6 @@ BOOST_AUTO_TEST_CASE(test_find_for_value) } } -BOOST_AUTO_TEST_CASE(test_find_for_table) -{ - // the value corresponding to the key is not the expected type - { - toml::table v{{"key", 42}}; - bool thrown = false; - try - { - toml::find(v, "key"); - } - catch(toml::type_error const& te) - { - thrown = true; - } - BOOST_CHECK(thrown); - } - - { - toml::table v{{"num", 42}}; - BOOST_CHECK_EQUAL(42, toml::find(v, "num")); - - // reference that can be used to modify the content - auto& num = toml::find(v, "num"); - num = 54; - BOOST_CHECK_EQUAL(54, toml::find(v, "num")); - } - - // recursive search is not provided for tables. -} - - BOOST_AUTO_TEST_CASE(test_get_or) { // requires conversion int -> uint @@ -176,75 +145,9 @@ BOOST_AUTO_TEST_CASE(test_get_or) BOOST_AUTO_TEST_CASE(test_find_or) { - // ======================================================================== - // pass toml::value - // // requires conversion int -> uint { - toml::table v{{"num", 42}}; - BOOST_CHECK_EQUAL(42u, toml::find_or(v, "num", 0u)); - BOOST_CHECK_EQUAL(0u, toml::find_or(v, "foo", 0u)); - } - // exact toml type - { - toml::table v1{{"key", 42 }}; - toml::table v2{{"key", 3.14}}; - toml::table v3{{"not", "key"}}; - - toml::integer opt(0); - BOOST_CHECK_EQUAL(42, toml::find_or(v1, "key", opt)); - BOOST_CHECK_EQUAL(0, toml::find_or(v2, "key", opt)); - BOOST_CHECK_EQUAL(0, toml::find_or(v3, "key", opt)); - - toml::table v4{{"str", "foobar"}}; - toml::string s("bazqux"); - - BOOST_CHECK_EQUAL("foobar", toml::find_or(v4, "str", s)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v1, "str", s)); - } - // std::string - { - toml::table v1{{"key", "foobar"}}; - toml::table v2{{"key", 42}}; - - std::string s1("bazqux"); - const std::string s2("bazqux"); - - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s1)); - BOOST_CHECK_EQUAL("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_CHECK_EQUAL("foobar", v1r); - BOOST_CHECK_EQUAL("bazqux", s1r); - - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s2)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s2)); - - BOOST_CHECK_EQUAL("foobar", toml::find_or(std::move(v1), "key", std::move(s1))); - s1 = "bazqux"; // restoring moved value - BOOST_CHECK_EQUAL("bazqux", toml::find_or(std::move(v2), "key", std::move(s1))); - } - // string literal - { - toml::table v1{{"key", "foobar"}}; - toml::table v2{{"key",42}}; - - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", "bazqux")); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", "bazqux")); - - const char* lit = "bazqux"; - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", lit)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", lit)); - } - - // ======================================================================== - // pass toml::value - // - // requires conversion int -> uint - { - toml::table v = toml::table{{"num", 42}}; + toml::value v = toml::table{{"num", 42}}; BOOST_CHECK_EQUAL(42u, toml::find_or(v, "num", 0u)); BOOST_CHECK_EQUAL(0u, toml::find_or(v, "foo", 0u)); } From 5cb7c961aac27517498b2d8fedb1b77ee4a42f51 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:26:41 +0900 Subject: [PATCH 077/162] fix: update README --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d2908f7..3be2497 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ int main() - [Integration](#integration) - [Decoding a toml file](#decoding-a-toml-file) - [In the case of syntax error](#in-the-case-of-syntax-error) + - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) - [Finding a toml value](#getting-a-toml-value) - [In the case of type error](#in-the-case-of-type-error) - [Dotted keys](#dotted-keys) @@ -65,7 +66,6 @@ int main() - [Customizing containers](#customizing-containers) - [TOML literal](#toml-literal) - [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) -- [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) - [Formatting user-defined error messages](#formatting-user-defined-error-messages) - [Getting comments related to a value](#getting-comments) - [Serializing TOML data](#serializing-toml-data) @@ -801,8 +801,9 @@ You can also append comments. The interfaces are the same as `std::vector Date: Mon, 17 Jun 2019 22:40:52 +0900 Subject: [PATCH 078/162] fix: correctly move value from find_or to get_or --- toml/get.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/get.hpp b/toml/get.hpp index 2314f32..5d37cd9 100644 --- a/toml/get.hpp +++ b/toml/get.hpp @@ -792,7 +792,7 @@ find_or(basic_value&& v, const toml::key& ky, T&& opt) if(!v.is_table()) {return std::forward(opt);} auto tab = toml::get(std::move(v)); if(tab.count(ky) == 0) {return std::forward(opt);} - return get_or(std::move(tab[ky]), std::forward(opt)); + return get_or(std::move(tab.at(ky)), std::forward(opt)); } // --------------------------------------------------------------------------- From c2b0de623f03fee762337321f2488a3948aa2a2c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:50:14 +0900 Subject: [PATCH 079/162] feat: enable to convert map-like to toml::value --- toml/value.hpp | 53 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index d1962f7..bfa5887 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -796,7 +796,7 @@ class basic_value basic_value& operator=(std::initializer_list list) { this->cleanup(); - this->type_ = value_t::array ; + this->type_ = value_t::array; this->region_info_ = std::make_shared(region_base{}); array_type ary; ary.reserve(list.size()); @@ -805,8 +805,10 @@ class basic_value return *this; } - template::value, - std::nullptr_t>::type = nullptr> + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> basic_value(T&& list) : type_(value_t::array), region_info_(std::make_shared(region_base{})) @@ -815,12 +817,14 @@ class basic_value for(const auto& elem : list) {ary.emplace_back(elem);} assigner(this->array_, std::move(ary)); } - template::value, - std::nullptr_t>::type = nullptr> + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> basic_value& operator=(T&& list) { this->cleanup(); - this->type_ = value_t::array ; + this->type_ = value_t::array; this->region_info_ = std::make_shared(region_base{}); array_type ary; ary.reserve(list.size()); @@ -848,11 +852,14 @@ class basic_value basic_value& operator=(const table_type& tab) { this->cleanup(); - this->type_ = value_t::table ; + this->type_ = value_t::table; this->region_info_ = std::make_shared(region_base{}); assigner(this->table_, tab); return *this; } + + // initializer-list ------------------------------------------------------ + basic_value(std::initializer_list> list) : type_(value_t::table), region_info_(std::make_shared(region_base{})) @@ -864,7 +871,7 @@ class basic_value basic_value& operator=(std::initializer_list> list) { this->cleanup(); - this->type_ = value_t::array ; + this->type_ = value_t::table; this->region_info_ = std::make_shared(region_base{}); table_type tab; @@ -873,6 +880,36 @@ class basic_value return *this; } + // other table-like ----------------------------------------------------- + + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value(const Map& mp) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})) + { + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value& operator=(const Map& mp) + { + this->cleanup(); + this->type_ = value_t::table; + this->region_info_ = std::make_shared(region_base{}); + + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + return *this; + } + // user-defined ========================================================= // convert using into_toml() method ------------------------------------- From 4008c24e84c48577c4e9e8d820a4850f89fae7f2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 22:50:38 +0900 Subject: [PATCH 080/162] test: add test for init-list-map to value conversion --- tests/test_value.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/test_value.cpp b/tests/test_value.cpp index d9cfca3..ee0f003 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -817,7 +817,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK(v1.is_table()); BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 42); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); + BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "qux"); BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_integer(), 42); BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_floating(), 3.14); @@ -826,6 +826,19 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK_EQUAL(v1.as_table(std::nothrow).at("bar").as_floating(), 3.14); BOOST_CHECK_EQUAL(v1.as_table(std::nothrow).at("baz").as_string().str, "qux"); + v1 = {{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; + + BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); + BOOST_CHECK(v1.is(toml::value_t::table)); + BOOST_CHECK(v1.is()); + BOOST_CHECK(v1.is_table()); + + BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); + BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); + BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); + BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_floating(), 2.71); + BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_integer(), 54); + BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "quux"); v1 = toml::table{{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; @@ -849,7 +862,7 @@ BOOST_AUTO_TEST_CASE(test_value_table) BOOST_CHECK(v3.is()); BOOST_CHECK(v3.is_table()); - BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); + BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); BOOST_CHECK_EQUAL(v3.cast().at("bar").cast(), 54); BOOST_CHECK_EQUAL(v3.cast().at("baz").cast().str, "quux"); BOOST_CHECK_EQUAL(v3.as_table().at("foo").as_floating(), 2.71); From bc68a9d9ee4ef4f4a0e874e63d0588501adaad66 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 23:07:14 +0900 Subject: [PATCH 081/162] refactor: remove needless include file --- toml/value.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/toml/value.hpp b/toml/value.hpp index bfa5887..278c78e 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -4,7 +4,6 @@ #define TOML11_VALUE_HPP #include "traits.hpp" #include "into.hpp" -#include "from.hpp" #include "utility.hpp" #include "exception.hpp" #include "storage.hpp" From 4d267cadf4d6fff53f8fe47a221224f2c9246486 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 23:12:46 +0900 Subject: [PATCH 082/162] doc: add templatized conversion to README --- README.md | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3be2497..d1acaf1 100644 --- a/README.md +++ b/README.md @@ -895,12 +895,10 @@ add a comma after the first element (like `[1,]`). NOTE: `_toml` literal returns a `toml::value` that does not have comments. - - ## Conversion between toml value and arbitrary types -You can also use `toml::get` and other related functions with the types you defined -after you implement some stuff. +You can also use `toml::get` and other related functions with the types +you defined after you implement a way to convert it. ```cpp namespace ext @@ -915,7 +913,8 @@ struct foo const auto data = toml::parse("example.toml"); -const foo f = toml::get(data.at("foo")); +// to do this +const foo f = toml::find(data, "foo"); ``` There are 2 ways to use `toml::get` with the types that you defined. @@ -963,12 +962,12 @@ namespace toml template<> struct from { - ext::foo from_toml(const toml::value& v) + ext::foo from_toml(const value& v) { ext::foo f; - f.a = toml::find(v, "a"); - f.b = toml::find(v, "b"); - f.c = toml::find(v, "c"); + f.a = find(v, "a"); + f.b = find(v, "b"); + f.c = find(v, "c"); return f; } }; @@ -981,6 +980,40 @@ you can add conversion between `toml::value` and classes defined in another libr Note that you cannot implement both of the functions because the overload resolution of `toml::get` will be ambiguous. +If you want to convert arbitrary specialization of `toml::basic_value`, +templatize the conversion function as follows. + +```cpp +struct foo +{ + template class M, template class A> + void from_toml(const toml::basic_value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + this->c = toml::find(v, "c"); + return; + } +}; +// or +namespace toml +{ +template<> +struct from +{ + template class M, template class A> + ext::foo from_toml(const basic_value& v) + { + ext::foo f; + f.a = find(v, "a"); + f.b = find(v, "b"); + f.c = find(v, "c"); + return f; + } +}; +} // toml +``` + ---- The opposite direction is also supported in a similar way. You can directly From bf2dc76d5e6bb41860dddc126f4c82d328e7749a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 23:21:18 +0900 Subject: [PATCH 083/162] test: add test for templatized conversions --- tests/test_extended_conversions.cpp | 249 +++++++++++++++++++++++----- 1 file changed, 211 insertions(+), 38 deletions(-) diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp index fd5d88d..8db1d02 100644 --- a/tests/test_extended_conversions.cpp +++ b/tests/test_extended_conversions.cpp @@ -54,63 +54,236 @@ struct into }; } // toml +// --------------------------------------------------------------------------- + +namespace extlib2 +{ +struct foo +{ + int a; + std::string b; +}; +struct bar +{ + int a; + std::string b; + + template class M, template class A> + void from_toml(const toml::basic_value& v) + { + this->a = toml::find(v, "a"); + this->b = toml::find(v, "b"); + return ; + } + + toml::table into_toml() const + { + return toml::table{{"a", this->a}, {"b", this->b}}; + } +}; +} // extlib2 + +namespace toml +{ +template<> +struct from +{ + template class M, template class A> + static extlib2::foo from_toml(const toml::basic_value& v) + { + return extlib2::foo{toml::find(v, "a"), toml::find(v, "b")}; + } +}; + +template<> +struct into +{ + 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 toml::value v{{"a", 42}, {"b", "baz"}}; - const auto foo = toml::get(v); - BOOST_CHECK_EQUAL(foo.a, 42); - BOOST_CHECK_EQUAL(foo.b, "baz"); + const auto foo = toml::get(v); + BOOST_CHECK_EQUAL(foo.a, 42); + BOOST_CHECK_EQUAL(foo.b, "baz"); - const toml::value v2(foo); + const toml::value v2(foo); - BOOST_CHECK_EQUAL(v, v2); + BOOST_CHECK_EQUAL(v, v2); + } + + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_CHECK_EQUAL(foo.a, 42); + BOOST_CHECK_EQUAL(foo.b, "baz"); + + const toml::value v2(foo); + + BOOST_CHECK_EQUAL(v, v2); + } + + { + const toml::basic_value + v{{"a", 42}, {"b", "baz"}}; + + const auto foo = toml::get(v); + BOOST_CHECK_EQUAL(foo.a, 42); + BOOST_CHECK_EQUAL(foo.b, "baz"); + + const toml::value v2(foo); + + BOOST_CHECK_EQUAL(v, v2); + } } BOOST_AUTO_TEST_CASE(test_conversion_by_specialization) { - const toml::value v{{"a", 42}, {"b", "baz"}}; + { + const toml::value v{{"a", 42}, {"b", "baz"}}; - const auto bar = toml::get(v); - BOOST_CHECK_EQUAL(bar.a, 42); - BOOST_CHECK_EQUAL(bar.b, "baz"); + const auto bar = toml::get(v); + BOOST_CHECK_EQUAL(bar.a, 42); + BOOST_CHECK_EQUAL(bar.b, "baz"); - const toml::value v2(bar); + const toml::value v2(bar); - BOOST_CHECK_EQUAL(v, v2); + BOOST_CHECK_EQUAL(v, v2); + } + { + const toml::value v{{"a", 42}, {"b", "baz"}}; + + const auto bar = toml::get(v); + BOOST_CHECK_EQUAL(bar.a, 42); + BOOST_CHECK_EQUAL(bar.b, "baz"); + + const toml::value v2(bar); + + BOOST_CHECK_EQUAL(v, v2); + } + { + const toml::basic_value + v{{"a", 42}, {"b", "baz"}}; + + const auto bar = toml::get(v); + BOOST_CHECK_EQUAL(bar.a, 42); + BOOST_CHECK_EQUAL(bar.b, "baz"); + + const toml::value v2(bar); + + BOOST_CHECK_EQUAL(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 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>(v); - BOOST_CHECK_EQUAL(foos.size() , 4ul); - BOOST_CHECK_EQUAL(foos.at(0).a , 42); - BOOST_CHECK_EQUAL(foos.at(1).a , 43); - BOOST_CHECK_EQUAL(foos.at(2).a , 44); - BOOST_CHECK_EQUAL(foos.at(3).a , 45); + const auto foos = toml::get>(v); + BOOST_CHECK_EQUAL(foos.size() , 4ul); + BOOST_CHECK_EQUAL(foos.at(0).a , 42); + BOOST_CHECK_EQUAL(foos.at(1).a , 43); + BOOST_CHECK_EQUAL(foos.at(2).a , 44); + BOOST_CHECK_EQUAL(foos.at(3).a , 45); - BOOST_CHECK_EQUAL(foos.at(0).b , "baz"); - BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); - BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); - BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + BOOST_CHECK_EQUAL(foos.at(0).b , "baz"); + BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); + BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); + BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); - const auto bars = toml::get>(v); - BOOST_CHECK_EQUAL(bars.size() , 4ul); - BOOST_CHECK_EQUAL(bars.at(0).a , 42); - BOOST_CHECK_EQUAL(bars.at(1).a , 43); - BOOST_CHECK_EQUAL(bars.at(2).a , 44); - BOOST_CHECK_EQUAL(bars.at(3).a , 45); + const auto bars = toml::get>(v); + BOOST_CHECK_EQUAL(bars.size() , 4ul); + BOOST_CHECK_EQUAL(bars.at(0).a , 42); + BOOST_CHECK_EQUAL(bars.at(1).a , 43); + BOOST_CHECK_EQUAL(bars.at(2).a , 44); + BOOST_CHECK_EQUAL(bars.at(3).a , 45); - BOOST_CHECK_EQUAL(bars.at(0).b , "baz"); - BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); - BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); - BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + BOOST_CHECK_EQUAL(bars.at(0).b , "baz"); + BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); + BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); + BOOST_CHECK_EQUAL(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>(v); + BOOST_CHECK_EQUAL(foos.size() , 4ul); + BOOST_CHECK_EQUAL(foos.at(0).a , 42); + BOOST_CHECK_EQUAL(foos.at(1).a , 43); + BOOST_CHECK_EQUAL(foos.at(2).a , 44); + BOOST_CHECK_EQUAL(foos.at(3).a , 45); + + BOOST_CHECK_EQUAL(foos.at(0).b , "baz"); + BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); + BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); + BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + + const auto bars = toml::get>(v); + BOOST_CHECK_EQUAL(bars.size() , 4ul); + BOOST_CHECK_EQUAL(bars.at(0).a , 42); + BOOST_CHECK_EQUAL(bars.at(1).a , 43); + BOOST_CHECK_EQUAL(bars.at(2).a , 44); + BOOST_CHECK_EQUAL(bars.at(3).a , 45); + + BOOST_CHECK_EQUAL(bars.at(0).b , "baz"); + BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); + BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); + BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + } + + { + const toml::basic_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>(v); + BOOST_CHECK_EQUAL(foos.size() , 4ul); + BOOST_CHECK_EQUAL(foos.at(0).a , 42); + BOOST_CHECK_EQUAL(foos.at(1).a , 43); + BOOST_CHECK_EQUAL(foos.at(2).a , 44); + BOOST_CHECK_EQUAL(foos.at(3).a , 45); + + BOOST_CHECK_EQUAL(foos.at(0).b , "baz"); + BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); + BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); + BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + + const auto bars = toml::get>(v); + BOOST_CHECK_EQUAL(bars.size() , 4ul); + BOOST_CHECK_EQUAL(bars.at(0).a , 42); + BOOST_CHECK_EQUAL(bars.at(1).a , 43); + BOOST_CHECK_EQUAL(bars.at(2).a , 44); + BOOST_CHECK_EQUAL(bars.at(3).a , 45); + + BOOST_CHECK_EQUAL(bars.at(0).b , "baz"); + BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); + BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); + BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + } } + From f744a792e2dcfe9712d06cf596c9606b3cda607d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 23:45:43 +0900 Subject: [PATCH 084/162] fix: constructor with array-like types --- toml/value.hpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 278c78e..71e84de 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -779,18 +779,17 @@ class basic_value } template::value, + std::is_convertible::value, std::nullptr_t>::type = nullptr> basic_value(std::initializer_list list) : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array_type ary; ary.reserve(list.size()); - for(auto& elem : list) {ary.emplace_back(std::move(elem));} + array_type ary(list.begin(), list.end()); assigner(this->array_, std::move(ary)); } template::value, + std::is_convertible::value, std::nullptr_t>::type = nullptr> basic_value& operator=(std::initializer_list list) { @@ -798,8 +797,7 @@ class basic_value this->type_ = value_t::array; this->region_info_ = std::make_shared(region_base{}); - array_type ary; ary.reserve(list.size()); - for(auto& elem : list) {ary.emplace_back(std::move(elem));} + array_type ary(list.begin(), list.end()); assigner(this->array_, std::move(ary)); return *this; } From 228487eafdd1810a9cf0db9c4e90e05903167190 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Mon, 17 Jun 2019 23:46:42 +0900 Subject: [PATCH 085/162] test: fix typos in tests --- tests/test_extended_conversions.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp index 8db1d02..c942a4e 100644 --- a/tests/test_extended_conversions.cpp +++ b/tests/test_extended_conversions.cpp @@ -134,14 +134,15 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods) } { - const toml::basic_value + const toml::basic_value v{{"a", 42}, {"b", "baz"}}; const auto foo = toml::get(v); BOOST_CHECK_EQUAL(foo.a, 42); BOOST_CHECK_EQUAL(foo.b, "baz"); - const toml::value v2(foo); + const toml::basic_value + v2(foo); BOOST_CHECK_EQUAL(v, v2); } @@ -172,14 +173,15 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_specialization) BOOST_CHECK_EQUAL(v, v2); } { - const toml::basic_value + const toml::basic_value v{{"a", 42}, {"b", "baz"}}; const auto bar = toml::get(v); BOOST_CHECK_EQUAL(bar.a, 42); BOOST_CHECK_EQUAL(bar.b, "baz"); - const toml::value v2(bar); + const toml::basic_value + v2(bar); BOOST_CHECK_EQUAL(v, v2); } @@ -253,12 +255,12 @@ BOOST_AUTO_TEST_CASE(test_recursive_conversion) } { - const toml::basic_value + const toml::basic_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"}}, + toml::table{{"a", 45}, {"b", "foobar"}} }; const auto foos = toml::get>(v); From 7b1a788e2d680b7195807256d28373de1bf0d121 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 00:43:25 +0900 Subject: [PATCH 086/162] feat: enable to convert vector to comments --- toml/comments.hpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/toml/comments.hpp b/toml/comments.hpp index 28ba28e..97ab610 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -55,6 +55,17 @@ struct preserve_comments explicit preserve_comments(std::vector&& c) : comments(std::move(c)) {} + preserve_comments& operator=(const std::vector& c) + { + comments = c; + return *this; + } + preserve_comments& operator=(std::vector&& c) + { + comments = std::move(c); + return *this; + } + explicit preserve_comments(const discard_comments&) {} explicit preserve_comments(size_type n): comments(n) {} @@ -278,6 +289,9 @@ struct discard_comments explicit discard_comments(const std::vector&) noexcept {} explicit discard_comments(std::vector&&) noexcept {} + discard_comments& operator=(const std::vector&) noexcept {return *this;} + discard_comments& operator=(std::vector&&) noexcept {return *this;} + explicit discard_comments(const preserve_comments&) noexcept {} explicit discard_comments(size_type) noexcept {} From ca084abe9002794bd9585b7144cddb99343449a3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 00:44:27 +0900 Subject: [PATCH 087/162] feat: consider the first comments as a file comment --- toml/parser.hpp | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index 6cc028b..b8a34cc 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1703,6 +1703,44 @@ result parse_toml_file(location& loc) return ok(value_type(table_type{})); } + // put the first line as a region of a file + const region file(loc, loc.iter(), + std::find(loc.iter(), loc.end(), '\n')); + + // The first successive comments that are separated from the first value + // by an empty line are for a file itself. + // ```toml + // # this is a comment for a file. + // + // key = "the first value" + // ``` + // ```toml + // # this is a comment for "the first value". + // key = "the first value" + // ``` + std::vector comments; + using lex_first_comments = sequence< + repeat, lex_comment, lex_newline>, at_least<1>>, + sequence, lex_newline> + >; + if(const auto token = lex_first_comments::invoke(loc)) + { + location inner_loc(loc.name(), token.unwrap().str()); + while(inner_loc.iter() != inner_loc.end()) + { + maybe::invoke(inner_loc); // remove ws if exists + if(lex_newline::invoke(inner_loc)) + { + assert(inner_loc.iter() == inner_loc.end()); + break; // empty line found. + } + auto com = lex_comment::invoke(inner_loc).unwrap().str(); + com.erase(com.begin()); // remove # sign + comments.push_back(std::move(com)); + lex_newline::invoke(inner_loc); + } + } + table_type data; // root object is also a table, but without [tablename] if(auto tab = parse_ml_table(loc)) @@ -1752,7 +1790,11 @@ result parse_toml_file(location& loc) return err(format_underline("[error]: toml::parse_toml_file: " "unknown line appeared", {{std::addressof(loc), "unknown format"}})); } - return ok(data); + + Value v(std::move(data), file); + v.comments() = comments; + + return ok(std::move(v)); } } // detail From fb5834caabd4682b17f81aa7b6ca96794b3cdff8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 00:45:30 +0900 Subject: [PATCH 088/162] refactor: exchange order of test section --- tests/test_parse_file.cpp | 343 +++++++++++++++++++------------------- 1 file changed, 172 insertions(+), 171 deletions(-) diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index ef3cf84..6283c04 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -194,6 +194,178 @@ BOOST_AUTO_TEST_CASE(test_hard_example) expected_multi_line_array); } +BOOST_AUTO_TEST_CASE(test_example_preserve_comment) +{ + const auto data = toml::parse("toml/tests/example.toml"); + + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_CHECK_EQUAL(alpha.comments().at(0), + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); + BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); + BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); + BOOST_CHECK_EQUAL(toml::find(beta, "country"), + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + "Hammer"); + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + 738594937); + + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + "Nail"); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + 284758393); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + "gray"); + } +} + +BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) +{ + const auto data = toml::parse("toml/tests/example.toml"); + + static_assert(std::is_same::type> + >::value, ""); + static_assert(std::is_same::type> + >::value, ""); + + BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + const auto& owner = toml::find(data, "owner"); + { + BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); + BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); + BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + "GitHub Cofounder & CEO\nLikes tater tots and beer."); + BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + " First class dates? Why not?"); + } + + const auto& database = toml::find(data, "database"); + { + BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + const std::vector expected_ports{8001, 8001, 8002}; + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); + BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); + BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + } + + const auto& servers = toml::find(data, "servers"); + { + const auto& alpha = toml::find(servers, "alpha"); + BOOST_CHECK_EQUAL(alpha.comments().at(0), + " You can indent as you please. Tabs or spaces. TOML don't care."); + BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); + BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + + const auto& beta = toml::find(servers, "beta"); + BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); + BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); + BOOST_CHECK_EQUAL(toml::find(beta, "country"), + "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + " This should be parsed as UTF-8"); + } + + const auto& clients = toml::find(data, "clients"); + { + BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + " just an update to make sure parsers support it"); + + + toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; + BOOST_CHECK(toml::get>(clients_data.at(0)) == + expected_name); + std::vector expected_number{1, 2}; + BOOST_CHECK(toml::get>(clients_data.at(1)) == + expected_number); + std::vector expected_hosts{"alpha", "omega"}; + BOOST_CHECK(toml::find>(clients, "hosts") == + expected_hosts); + + BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + " Line breaks are OK when inside arrays"); + } + + std::vector products = + toml::find>(data, "products"); + { + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + "Hammer"); + BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + 738594937); + + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + "Nail"); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + 284758393); + BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + "gray"); + } +} + // --------------------------------------------------------------------------- // after here, the test codes generate the content of a file. @@ -695,174 +867,3 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) } } -BOOST_AUTO_TEST_CASE(test_example_preserve_comment) -{ - const auto data = toml::parse("toml/tests/example.toml"); - - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); - const auto& owner = toml::find(data, "owner"); - { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), - " First class dates? Why not?"); - } - - const auto& database = toml::find(data, "database"); - { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); - } - - const auto& servers = toml::find(data, "servers"); - { - const auto& alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(alpha.comments().at(0), - " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); - - const auto& beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); - BOOST_CHECK_EQUAL(toml::find(beta, "country"), - "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), - " This should be parsed as UTF-8"); - } - - const auto& clients = toml::find(data, "clients"); - { - BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), - " just an update to make sure parsers support it"); - - - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); - - BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), - " Line breaks are OK when inside arrays"); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), - "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), - 738594937); - - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), - "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), - 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), - "gray"); - } -} - -BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) -{ - const auto data = toml::parse("toml/tests/example.toml"); - - static_assert(std::is_same::type> - >::value, ""); - static_assert(std::is_same::type> - >::value, ""); - - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); - const auto& owner = toml::find(data, "owner"); - { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), - "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), - " First class dates? Why not?"); - } - - const auto& database = toml::find(data, "database"); - { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); - const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); - } - - const auto& servers = toml::find(data, "servers"); - { - const auto& alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(alpha.comments().at(0), - " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); - - const auto& beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); - BOOST_CHECK_EQUAL(toml::find(beta, "country"), - "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), - " This should be parsed as UTF-8"); - } - - const auto& clients = toml::find(data, "clients"); - { - BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), - " just an update to make sure parsers support it"); - - - toml::array clients_data = toml::find(clients, "data"); - std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); - std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); - std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); - - BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), - " Line breaks are OK when inside arrays"); - } - - std::vector products = - toml::find>(data, "products"); - { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), - "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), - 738594937); - - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), - "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), - 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), - "gray"); - } -} From 159283fdad035ee77785a9c3eb198095ea3cfe52 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 01:25:43 +0900 Subject: [PATCH 089/162] test: check preserve_comment keep it read --- tests/test_parse_file.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index 6283c04..e2d499b 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -193,6 +193,34 @@ BOOST_AUTO_TEST_CASE(test_hard_example) BOOST_CHECK(toml::find>(bit, "multi_line_array") == expected_multi_line_array); } +BOOST_AUTO_TEST_CASE(test_hard_example_comment) +{ + const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto the = toml::find(data, "the"); + BOOST_CHECK_EQUAL(toml::find(the, "test_string"), + "You'll hate me after this - #"); + + const auto hard = toml::find(the, "hard"); + const std::vector expected_the_hard_test_array{"] ", " # "}; + BOOST_CHECK(toml::find>(hard, "test_array") == + expected_the_hard_test_array); + const std::vector expected_the_hard_test_array2{ + "Test #11 ]proved that", "Experiment #9 was a success"}; + BOOST_CHECK(toml::find>(hard, "test_array2") == + expected_the_hard_test_array2); + BOOST_CHECK_EQUAL(toml::find(hard, "another_test_string"), + " Same thing, but with a string #"); + BOOST_CHECK_EQUAL(toml::find(hard, "harder_test_string"), + " And when \"'s are in the string, along with # \""); + + const auto bit = toml::find(hard, "bit#"); + BOOST_CHECK_EQUAL(toml::find(bit, "what?"), + "You don't think some user won't do that?"); + const std::vector expected_multi_line_array{"]"}; + BOOST_CHECK(toml::find>(bit, "multi_line_array") == + expected_multi_line_array); +} + BOOST_AUTO_TEST_CASE(test_example_preserve_comment) { From 86e55c3bf7b3520589bca39aa4b50cd79f2f381d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 01:26:16 +0900 Subject: [PATCH 090/162] test: check serialization keeps comments --- tests/test_serialize_file.cpp | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 816dbbe..372249b 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -9,7 +9,6 @@ #include #include - BOOST_AUTO_TEST_CASE(test_example) { const auto data = toml::parse("toml/tests/example.toml"); @@ -31,6 +30,31 @@ BOOST_AUTO_TEST_CASE(test_example) BOOST_CHECK(data == serialized); } +BOOST_AUTO_TEST_CASE(test_example_with_comment) +{ + const auto data = toml::parse("toml/tests/example.toml"); + { + std::ofstream ofs("tmp1_com.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse("tmp1_com.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::get(owner.at("bio")); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } + BOOST_CHECK(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"); @@ -42,6 +66,17 @@ BOOST_AUTO_TEST_CASE(test_fruit) BOOST_CHECK(data == serialized); } +BOOST_AUTO_TEST_CASE(test_fruit_with_comments) +{ + const auto data = toml::parse("toml/tests/fruit.toml"); + { + std::ofstream ofs("tmp2_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp2_com.toml"); + BOOST_CHECK(data == serialized); +} + BOOST_AUTO_TEST_CASE(test_hard_example) { const auto data = toml::parse("toml/tests/hard_example.toml"); @@ -52,3 +87,18 @@ BOOST_AUTO_TEST_CASE(test_hard_example) const auto serialized = toml::parse("tmp3.toml"); BOOST_CHECK(data == serialized); } + +BOOST_AUTO_TEST_CASE(test_hard_example_with_comment) +{ + const auto data = toml::parse("toml/tests/hard_example.toml"); + { + std::ofstream ofs("tmp3_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp3_com.toml"); + { + std::ofstream ofs("tmp3_com1.toml"); + ofs << std::setw(80) << serialized; + } + BOOST_CHECK(data == serialized); +} From 262f9c5fcc8ea8e42c9f8fe084534659fddcb7b1 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 01:26:40 +0900 Subject: [PATCH 091/162] fix: avoid duplicating comment: array/table elems --- toml/region.hpp | 63 +++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index 987238b..e6a7e68 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -304,38 +304,45 @@ struct region final : public region_base // # this also. // a = value # not this. // ``` - auto iter = this->line_begin(); // points the first character - while(iter != this->begin()) + + // # 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 == '{';})) { - iter = std::prev(iter); + 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. - } + // 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)); + // 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; } - else - { - break; - } - iter = line_start; } } From 32d5c9e92413c7ff542e280ccb4de17276aac260 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 01:27:52 +0900 Subject: [PATCH 092/162] fix: serialize array correctly --- toml/serializer.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index b3e3637..cba2923 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -333,6 +333,11 @@ struct serializer current_line += ','; } } + if(!current_line.empty()) + { + if(current_line.back() != '\n') {current_line += '\n';} + token += current_line; + } token += "]\n"; return token; } From d9f9df61a2a02c737df1a50adf07d098d81f658a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 01:39:36 +0900 Subject: [PATCH 093/162] fix: fix links in README --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d1acaf1..3562f33 100644 --- a/README.md +++ b/README.md @@ -47,17 +47,17 @@ int main() - [Decoding a toml file](#decoding-a-toml-file) - [In the case of syntax error](#in-the-case-of-syntax-error) - [Invalid UTF-8 Codepoints](#invalid-utf-8-codepoints) -- [Finding a toml value](#getting-a-toml-value) +- [Finding a toml value](#finding-a-toml-value-from-a-table) - [In the case of type error](#in-the-case-of-type-error) - [Dotted keys](#dotted-keys) - [Casting a toml value](#casting-a-toml-value) - [Checking value type](#checking-value-type) - [More about conversion](#more-about-conversion) - - [Getting an array](#getting-an-array) - - [Getting a table](#getting-a-table) + - [Converting an array](#converting-an-array) + - [Converting a table](#converting-a-table) - [Getting an array of tables](#getting-an-array-of-tables) - [Cost of conversion](#cost-of-conversion) - - [Getting datetime and its variants](#getting-datetime-and-its-variants) + - [Converting datetime and its variants](#converting-datetime-and-its-variants) - [Getting with a fallback](#getting-with-a-fallback) - [Expecting conversion](#expecting-conversion) - [Visiting a toml::value](#visiting-a-tomlvalue) @@ -67,7 +67,6 @@ int main() - [TOML literal](#toml-literal) - [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) - [Formatting user-defined error messages](#formatting-user-defined-error-messages) -- [Getting comments related to a value](#getting-comments) - [Serializing TOML data](#serializing-toml-data) - [Underlying types](#underlying-types) - [Breaking Changes from v2](#breaking-changes-from-v2) @@ -710,7 +709,7 @@ const auto value = toml::expect(data.at("number")) }).unwrap_or(/*default value =*/ 3.14); ``` -## Visiting toml::value +## Visiting a toml::value toml11 provides `toml::visit` to apply a function to `toml::value` in the same way as `std::variant`. From 3613580bb38f7fec51802ba9be2840af0440f51d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Tue, 18 Jun 2019 21:26:17 +0900 Subject: [PATCH 094/162] doc: update README --- README.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d1acaf1..b300b5c 100644 --- a/README.md +++ b/README.md @@ -222,13 +222,20 @@ const toml::value& answer = toml::find(data, "answer"); **NOTE**: For some technical reason, automatic conversion between `integer` and `floating` is not supported. If you want to get a floating value even if a value -has integer value, you need to convert it manually after obtaining a value. +has integer value, you need to convert it manually after obtaining a value, +like the followings. + +```cpp +const auto vx = toml::find(data, "x"); +double x = vx.is_floating() ? vx.as_floating(std::nothrow) : + static_cast(vx.as_integer()); // it throws if vx is neither + // floating nor integer. +``` ---- -There are several ways to find a value buried in a deep recursion of tables. - -First, you can call `toml::find` as many as you need. +`toml::find` accepts arbitrary number of keys to find a value buried in a +deep recursion of tables. ```cpp // # expecting the following example.toml @@ -236,18 +243,12 @@ First, you can call `toml::find` as many as you need. // # is equivalent to {"answer": {"to":{"the":{"ultimate:{"question":42}}}}} const toml::table data = toml::parse("example.toml"); -const int a = toml::find(toml::find(toml::find(toml::find(toml::find( - data, "answer"), "to"), "the"), "ultimate"), "question"); -``` - -But it is a bother. Alternatively, you can pass several keys to `toml::find` to -find the value. - -```cpp -const toml::value data = toml::parse("example.toml"); const int a = toml::find(data, "answer", "to", "the", "ultimate", "question"); ``` +Of course, alternatively, you can call `toml::find` as many as you need. +But it is a bother. + ### In the case of type error If the specified type differs from the actual value contained, it throws @@ -728,7 +729,58 @@ each other. ## Constructing a toml::value -TODO +`toml::value` can be constructed in various ways. + +```cpp +toml::value v(true); // boolean +toml::value v(42); // integer +toml::value v(3.14); // floating +toml::value v("foobar"); // string +toml::value v(toml::local_date(2019, toml::month_t::Apr, 1)); // date +toml::value v{1, 2, 3, 4, 5}; // array +toml::value v{{"foo", 42}, {"bar", 3.14}, {"baz", "qux"}}; // table +``` + +When constructing a string, you can choose to use either literal or basic string. +By default, it will be a basic string. + +```cpp +toml::value v("foobar", toml::string_t::basic ); +toml::value v("foobar", toml::string_t::literal); +``` + +Datetime objects can be constructed from `std::tm` and +`std::chrono::system_clock::time_point`. But you need to specify what type +you use to avoid ambiguity. + +```cpp +const auto now = std::chrono::system_clock::now(); +toml::value v(toml::local_date(now)); +toml::value v(toml::local_datetime(now)); +toml::value v(toml::offset_datetime(now)); +``` + +Since local time is not equivalent to a time point, because it lacks date +information, it will be constructed from `std::chrono::duration`. + +```cpp +toml::value v(toml::local_time(std::chrono::hours(10))); +``` + +You can construct an array object not only from `initializer_list`, but also +from STL containers. + +```cpp +std::vector vec{1,2,3,4,5}; +toml::value v = vec; +``` + + + +```cpp +toml::value v = vec; +``` + ## Preserving comments @@ -808,6 +860,9 @@ All the modification on comments would be ignored. The comments will also be serialized. If comments exist, those comments will be added just before the values. +__NOTE__: Result types from `toml::parse(...)` and +`toml::parse(...)` are different. + ## Customizing containers Actually, `toml::basic_value` has 3 template arguments. @@ -831,6 +886,10 @@ const auto data = toml::parse< >("example.toml"); ``` +__NOTE__: Needless to say, the result types from `toml::parse(...)` and +`toml::parse(...)` are different (unless you specify the same +types as default). + ## TOML literal toml11 supports `"..."_toml` literal. From 3379ed82ec90e6cb26eb501d5c650068881e6ce6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 19 Jun 2019 20:06:06 +0900 Subject: [PATCH 095/162] refactor: remove meaningless meta conditions --- toml/value.hpp | 48 ++++++++---------------------------------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 74a5231..bc95ceb 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1430,16 +1430,8 @@ inline bool operator!=(const basic_value& lhs, const basic_value class T, template class A> typename std::enable_if::boolean_type >, - detail::is_comparable::integer_type >, - detail::is_comparable::floating_type >, - detail::is_comparable::string_type >, - detail::is_comparable::local_time_type >, - detail::is_comparable::local_date_type >, - detail::is_comparable::local_datetime_type >, - detail::is_comparable::offset_datetime_type >, - detail::is_comparable::array_type >, - detail::is_comparable::table_type > + detail::is_comparable::array_type>, + detail::is_comparable::table_type> >::value, bool>::type operator<(const basic_value& lhs, const basic_value& rhs) { @@ -1519,16 +1511,8 @@ operator<(const basic_value& lhs, const basic_value& rhs) template class T, template class A> typename std::enable_if::boolean_type >, - detail::is_comparable::integer_type >, - detail::is_comparable::floating_type >, - detail::is_comparable::string_type >, - detail::is_comparable::local_time_type >, - detail::is_comparable::local_date_type >, - detail::is_comparable::local_datetime_type >, - detail::is_comparable::offset_datetime_type >, - detail::is_comparable::array_type >, - detail::is_comparable::table_type > + detail::is_comparable::array_type>, + detail::is_comparable::table_type> >::value, bool>::type operator<=(const basic_value& lhs, const basic_value& rhs) { @@ -1536,16 +1520,8 @@ operator<=(const basic_value& lhs, const basic_value& rhs) } template class T, template class A> typename std::enable_if::boolean_type >, - detail::is_comparable::integer_type >, - detail::is_comparable::floating_type >, - detail::is_comparable::string_type >, - detail::is_comparable::local_time_type >, - detail::is_comparable::local_date_type >, - detail::is_comparable::local_datetime_type >, - detail::is_comparable::offset_datetime_type >, - detail::is_comparable::array_type >, - detail::is_comparable::table_type > + detail::is_comparable::array_type>, + detail::is_comparable::table_type> >::value, bool>::type operator>(const basic_value& lhs, const basic_value& rhs) { @@ -1553,16 +1529,8 @@ operator>(const basic_value& lhs, const basic_value& rhs) } template class T, template class A> typename std::enable_if::boolean_type >, - detail::is_comparable::integer_type >, - detail::is_comparable::floating_type >, - detail::is_comparable::string_type >, - detail::is_comparable::local_time_type >, - detail::is_comparable::local_date_type >, - detail::is_comparable::local_datetime_type >, - detail::is_comparable::offset_datetime_type >, - detail::is_comparable::array_type >, - detail::is_comparable::table_type > + detail::is_comparable::array_type>, + detail::is_comparable::table_type> >::value, bool>::type operator>=(const basic_value& lhs, const basic_value& rhs) { From f178379c07a44a276bd0547a9d781fe11f8c6a46 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 14:34:14 +0900 Subject: [PATCH 096/162] test: add test_find --- tests/CMakeLists.txt | 1 + tests/test_find.cpp | 380 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 tests/test_find.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 656d415..ef5eed5 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,6 +23,7 @@ set(TEST_NAMES test_literals test_comments test_get + test_find test_get_related_func test_parse_file test_serialize_file diff --git a/tests/test_find.cpp b/tests/test_find.cpp new file mode 100644 index 0000000..2029533 --- /dev/null +++ b/tests/test_find.cpp @@ -0,0 +1,380 @@ +#define BOOST_TEST_MODULE "test_find" + +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +#include +#else +#define BOOST_TEST_NO_LIB +#include +#endif + +#include +#include +#include +#include +#include +#include +#if __cplusplus >= 201703L +#include +#endif +#include + +using test_value_types = std::tuple< + toml::value, + toml::basic_value, + toml::basic_value, + toml::basic_value + >; + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) +{ + { + value_type v{{"key", true}}; + BOOST_CHECK_EQUAL(true, toml::find(v, "key")); + + toml::find(v, "key") = false; + BOOST_CHECK_EQUAL(false, toml::find(v, "key")); + } + { + value_type v{{"key", 42}}; + BOOST_CHECK_EQUAL(toml::integer(42), toml::find(v, "key")); + + toml::find(v, "key") = 54; + BOOST_CHECK_EQUAL(toml::integer(54), toml::find(v, "key")); + } + { + value_type v{{"key", 3.14}}; + BOOST_CHECK_EQUAL(toml::floating(3.14), toml::find(v, "key")); + + toml::find(v, "key") = 2.71; + BOOST_CHECK_EQUAL(toml::floating(2.71), toml::find(v, "key")); + } + { + value_type v{{"key", "foo"}}; + BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::basic), + toml::find(v, "key")); + + toml::find(v, "key").str += "bar"; + BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::basic), + toml::find(v, "key")); + } + { + value_type v{{"key", value_type("foo", toml::string_t::literal)}}; + BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::literal), + toml::find(v, "key")); + + toml::find(v, "key").str += "bar"; + BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::literal), + toml::find(v, "key")); + } + { + toml::local_date d(2018, toml::month_t::Apr, 22); + value_type v{{"key", d}}; + BOOST_CHECK(d == toml::find(v, "key")); + + toml::find(v, "key").year = 2017; + d.year = 2017; + BOOST_CHECK(d == toml::find(v, "key")); + } + { + toml::local_time t(12, 30, 45); + value_type v{{"key", t}}; + BOOST_CHECK(t == toml::find(v, "key")); + + toml::find(v, "key").hour = 9; + t.hour = 9; + BOOST_CHECK(t == toml::find(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(v, "key")); + + toml::find(v, "key").date.year = 2017; + dt.date.year = 2017; + BOOST_CHECK(dt == toml::find(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(v, "key")); + + toml::find(v, "key").date.year = 2017; + dt.date.year = 2017; + BOOST_CHECK(dt == toml::find(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(v, "key")); + BOOST_CHECK(result1); + + toml::find(v, "key").push_back(value_type(123)); + vec.push_back(value_type(123)); + + const bool result2 = (vec == toml::find(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(v, "key")); + BOOST_CHECK(result1); + + toml::find(v, "key")["key3"] = value_type(123); + tab["key3"] = value_type(123); + const bool result2 = (tab == toml::find(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_CHECK_EQUAL(int(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(short(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(char(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(unsigned(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(long(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(std::int64_t(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(std::uint64_t(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(std::int16_t(42), toml::find(v, "key")); + BOOST_CHECK_EQUAL(std::uint16_t(42), toml::find(v, "key")); + } +} + +BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_types) +{ + { + value_type v{{"key", 3.14}}; + BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(v, "key")); + BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(v, "key")); + BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(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_CHECK_EQUAL("foo", toml::find(v, "key")); + toml::find(v, "key") += "bar"; + BOOST_CHECK_EQUAL("foobar", toml::find(v, "key")); + } + { + value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; + BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + toml::find(v, "key") += "bar"; + BOOST_CHECK_EQUAL("foobar", toml::find(v, "key")); + } + +#if __cplusplus >= 201703L + { + value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; + BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + } + { + value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; + BOOST_CHECK_EQUAL("foo", toml::find(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 vec = toml::find>(v, "key"); + const std::list lst = toml::find>(v, "key"); + const std::deque deq = toml::find>(v, "key"); + + BOOST_CHECK_EQUAL(42, vec.at(0)); + BOOST_CHECK_EQUAL(54, vec.at(1)); + BOOST_CHECK_EQUAL(69, vec.at(2)); + BOOST_CHECK_EQUAL(72, vec.at(3)); + + std::list::const_iterator iter = lst.begin(); + BOOST_CHECK_EQUAL(static_cast(42), *(iter++)); + BOOST_CHECK_EQUAL(static_cast(54), *(iter++)); + BOOST_CHECK_EQUAL(static_cast(69), *(iter++)); + BOOST_CHECK_EQUAL(static_cast(72), *(iter++)); + + BOOST_CHECK_EQUAL(static_cast(42), deq.at(0)); + BOOST_CHECK_EQUAL(static_cast(54), deq.at(1)); + BOOST_CHECK_EQUAL(static_cast(69), deq.at(2)); + BOOST_CHECK_EQUAL(static_cast(72), deq.at(3)); + + std::array ary = toml::find>(v, "key"); + BOOST_CHECK_EQUAL(static_cast(42), ary.at(0)); + BOOST_CHECK_EQUAL(static_cast(54), ary.at(1)); + BOOST_CHECK_EQUAL(static_cast(69), ary.at(2)); + BOOST_CHECK_EQUAL(static_cast(72), ary.at(3)); + + std::tuple tpl = + toml::find>(v, "key"); + BOOST_CHECK_EQUAL(static_cast(42), std::get<0>(tpl)); + BOOST_CHECK_EQUAL(static_cast(54), std::get<1>(tpl)); + BOOST_CHECK_EQUAL(static_cast(69), std::get<2>(tpl)); + BOOST_CHECK_EQUAL(static_cast(72), std::get<3>(tpl)); + + value_type p{{"key", {3.14, 2.71}}}; + std::pair pr = toml::find >(p, "key"); + BOOST_CHECK_EQUAL(3.14, pr.first); + BOOST_CHECK_EQUAL(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> p = + toml::find, std::vector>>(v, "key"); + + BOOST_CHECK_EQUAL(p.first.at(0), 42); + BOOST_CHECK_EQUAL(p.first.at(1), 54); + BOOST_CHECK_EQUAL(p.first.at(2), 69); + BOOST_CHECK_EQUAL(p.first.at(3), 72); + + BOOST_CHECK_EQUAL(p.second.at(0), "foo"); + BOOST_CHECK_EQUAL(p.second.at(1), "bar"); + BOOST_CHECK_EQUAL(p.second.at(2), "baz"); + + std::tuple, std::vector> t = + toml::find, std::vector>>(v, "key"); + + BOOST_CHECK_EQUAL(std::get<0>(t).at(0), 42); + BOOST_CHECK_EQUAL(std::get<0>(t).at(1), 54); + BOOST_CHECK_EQUAL(std::get<0>(t).at(2), 69); + BOOST_CHECK_EQUAL(std::get<0>(t).at(3), 72); + + BOOST_CHECK_EQUAL(std::get<1>(t).at(0), "foo"); + BOOST_CHECK_EQUAL(std::get<1>(t).at(1), "bar"); + BOOST_CHECK_EQUAL(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>(v1, "key"); + BOOST_CHECK_EQUAL(v.at("key1"), 1); + BOOST_CHECK_EQUAL(v.at("key2"), 2); + BOOST_CHECK_EQUAL(v.at("key3"), 3); + BOOST_CHECK_EQUAL(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(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_CHECK_EQUAL(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(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(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_CHECK_EQUAL(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(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_CHECK_EQUAL(tm.tm_year + 1900, 2018); + BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); + BOOST_CHECK_EQUAL(tm.tm_mday, 1); + BOOST_CHECK_EQUAL(tm.tm_hour, 3); + BOOST_CHECK_EQUAL(tm.tm_min, 30); + BOOST_CHECK_EQUAL(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(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_CHECK_EQUAL(tm.tm_year + 1900, 2018); + BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); + BOOST_CHECK_EQUAL(tm.tm_mday, 1); + BOOST_CHECK_EQUAL(tm.tm_hour, 20); + BOOST_CHECK_EQUAL(tm.tm_min, 30); + BOOST_CHECK_EQUAL(tm.tm_sec, 0); + } +} + From 5e5a7572087df6c37ecadf3e86482fc35500c388 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 14:35:38 +0900 Subject: [PATCH 097/162] fix: conversion between different basic_value s --- toml/value.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index bc95ceb..52d7b43 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -406,7 +406,7 @@ class basic_value basic_value& operator=(const basic_value& v) { this->region_info_ = v.region_info_; - this->comments_ = v.comments(); + this->comments_ = comment_type(v.comments()); this->type_ = v.type(); switch(v.type()) { @@ -806,26 +806,32 @@ class basic_value detail::negation>, detail::is_container >::value, std::nullptr_t>::type = nullptr> - basic_value(T&& list) + basic_value(const T& list) : type_(value_t::array), region_info_(std::make_shared(region_base{})) { - array_type ary; ary.reserve(list.size()); - for(const auto& elem : list) {ary.emplace_back(elem);} + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); assigner(this->array_, std::move(ary)); } template>, detail::is_container >::value, std::nullptr_t>::type = nullptr> - basic_value& operator=(T&& list) + basic_value& operator=(const T& list) { + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + this->cleanup(); this->type_ = value_t::array; this->region_info_ = std::make_shared(region_base{}); - array_type ary; ary.reserve(list.size()); - for(const auto& elem : list) {ary.emplace_back(elem);} + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); assigner(this->array_, std::move(ary)); return *this; } @@ -1375,6 +1381,7 @@ operator==(const basic_value& lhs, const basic_value& rhs) { if(lhs.type() != rhs.type()) {return false;} if(lhs.comments() != rhs.comments()) {return false;} + switch(lhs.type()) { case value_t::boolean : From c3922c0d51ec56d279297ed69cca5828dd421beb Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 14:43:31 +0900 Subject: [PATCH 098/162] test: move some test_cases across test files --- tests/test_find.cpp | 52 ++++++++++++++++++++++++++++++++ tests/test_get_related_func.cpp | 53 --------------------------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 2029533..2ed4167 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -25,6 +25,58 @@ using test_value_types = std::tuple< toml::basic_value >; +BOOST_AUTO_TEST_CASE(test_find_throws) +{ + { + // value is not a table + toml::value v(true); + BOOST_CHECK_THROW(toml::find(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(v, "key"), toml::type_error); + } + { + // the value corresponding to the key is not found + toml::value v{{"key", 42}}; + BOOST_CHECK_THROW(toml::find(v, "different_key"), + std::out_of_range); + } + { + // the positive control. + toml::value v{{"key", 42}}; + BOOST_CHECK_EQUAL(42, toml::find(v, "key")); + } +} + +BOOST_AUTO_TEST_CASE(test_find_recursive) +{ + // recursively search tables + { + toml::value v{ + {"a", { + {"b", { + {"c", { + {"d", 42} + }} + }} + }} + }; + BOOST_CHECK_EQUAL(42, toml::find(v, "a", "b", "c", "d")); + + // reference that can be used to modify the content + auto& num = toml::find(v, "a", "b", "c", "d"); + num = 54; + BOOST_CHECK_EQUAL(54, toml::find(v, "a", "b", "c", "d")); + + const std::string a("a"), b("b"), c("c"), d("d"); + auto& num2 = toml::find(v, a, b, c, d); + num2 = 42; + BOOST_CHECK_EQUAL(42, toml::find(v, a, b, c, d)); + } +} + BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) { { diff --git a/tests/test_get_related_func.cpp b/tests/test_get_related_func.cpp index c0fcff6..496b1b7 100644 --- a/tests/test_get_related_func.cpp +++ b/tests/test_get_related_func.cpp @@ -12,60 +12,7 @@ #include #include -BOOST_AUTO_TEST_CASE(test_find) -{ - { - toml::value v(true); - bool thrown = false; - try - { - toml::find(v, "key"); - } - catch(toml::type_error const& te) - { - thrown = true; - } - BOOST_CHECK(thrown); - } - // the value corresponding to the key is not the expected type - { - toml::value v{{"key", 42}}; - bool thrown = false; - try - { - toml::find(v, "key"); - } - catch(toml::type_error const& te) - { - thrown = true; - } - BOOST_CHECK(thrown); - } - // recursively search tables - { - toml::value v = toml::table{ - {"a", toml::table{ - {"b", toml::table{ - {"c", toml::table{ - {"d", 42} - }} - }} - }} - }; - BOOST_CHECK_EQUAL(42, toml::find(v, "a", "b", "c", "d")); - - // reference that can be used to modify the content - auto& num = toml::find(v, "a", "b", "c", "d"); - num = 54; - BOOST_CHECK_EQUAL(54, toml::find(v, "a", "b", "c", "d")); - - const std::string a("a"), b("b"), c("c"), d("d"); - auto& num2 = toml::find(v, a, b, c, d); - num2 = 42; - BOOST_CHECK_EQUAL(42, toml::find(v, a, b, c, d)); - } -} BOOST_AUTO_TEST_CASE(test_get_or) { From a0d74a5542c9a19629edb23bfa159de8d421b28c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 14:57:54 +0900 Subject: [PATCH 099/162] doc: add info about breaking changes to README --- README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9ceaa54..6417f50 100644 --- a/README.md +++ b/README.md @@ -1376,15 +1376,18 @@ Between v2 and v3, those interfaces are rearranged. - Supports for the CamelCaseNames are dropped. - See [Underlying types](#underlying-types) for detail. - `(is|as)_float` has been removed to make the function names consistent with others. - Since `float` is a keyword, toml11 named a float type as `toml::floating`. - Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. - So `(is|as)_floating` is introduced and `is_float` has been removed. + - Since `float` is a keyword, toml11 named a float type as `toml::floating`. + - Also a `value_t` corresponds to `toml::floating` is named `value_t::floating`. + - So `(is|as)_floating` is introduced and `is_float` has been removed. - See [Casting a toml::value](#casting-a-tomlvalue) and [Checking value type](#checking-value-type) for detail. -- `toml::find` for `toml::table` has been dropped. Use `toml::value` version instead. +- An overload of `toml::find` for `toml::table` has been dropped. Use `toml::value` version instead. + - Because type conversion between a table and a value causes ambiguity while overload resolution + - Also because `toml::table` is a normal STL container, implementing utility function is easy. - See [Finding a toml::value](#finding-a-tomlvalue) for detail. - Interface around comments. - See [Preserving Comments](#preserving-comments) for detail. -- An old `from_toml` has been removed +- An ancient `from_toml/into_toml` has been removed. Use arbitrary type conversion support. + - See [Conversion between toml value and arbitrary types](#conversion-between-toml-value-and-arbitrary-types) for detail. Such a big change will not happen in the coming years. From 7d087ef2a8ab70b5a2ca3f42bc66da68f1a76b40 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 15:22:20 +0900 Subject: [PATCH 100/162] doc: update README --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 6417f50..9748bf4 100644 --- a/README.md +++ b/README.md @@ -704,10 +704,6 @@ toml::integer opt = 42; toml::integer& i = toml::get_or(v, opt); // this works. ``` -There is also a function `find_or`, but there is a known issue around overload -resolution. To use it, passing a `toml::value`, not a `toml::table`, is strongly -recommended. - ## Expecting conversion By using `toml::expect`, you will get your expected value or an error message From 99c10dd6bc97ba0c6503b94bbc4265d6ecf9a60d Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 16:21:01 +0900 Subject: [PATCH 101/162] fix: enable to deduce what basic_value to be used --- tests/check_toml_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/check_toml_test.cpp b/tests/check_toml_test.cpp index aeaf54a..ec03124 100644 --- a/tests/check_toml_test.cpp +++ b/tests/check_toml_test.cpp @@ -84,8 +84,8 @@ struct json_serializer { if(!is_first) {std::cout << ", ";} is_first = false; - std::cout << toml::format(toml::string(elem.first), - std::numeric_limits::max()); + std::cout << toml::format(toml::value(elem.first), + std::numeric_limits::max()); std::cout << ':'; toml::visit(*this, elem.second); } From 86a1f7ad75d96c38146bed6b38fbf9ee4f242285 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 16:23:51 +0900 Subject: [PATCH 102/162] fix: add missing include files --- tests/test_extended_conversions.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp index c942a4e..2b2f430 100644 --- a/tests/test_extended_conversions.cpp +++ b/tests/test_extended_conversions.cpp @@ -6,6 +6,8 @@ #include #endif #include +#include +#include namespace extlib { From 48aa0a4c676dfb1ae8c8189c0961a61438983453 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 19:53:27 +0900 Subject: [PATCH 103/162] ci: update boost version on appveyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index cd8d102..6812d59 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,7 +19,7 @@ build_script: - cd build - git clone https://github.com/toml-lang/toml.git - 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%" test_script: From 37b4442d7f2913f56c0ccf4266996194d013b33a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:00:56 +0900 Subject: [PATCH 104/162] ci: upgrade boost on Travis Linux --- .travis.yml | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08de4ac..4fcca8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,9 +10,10 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-5 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: gcc @@ -21,9 +22,10 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-6 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: gcc @@ -32,9 +34,10 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-7 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: gcc @@ -43,9 +46,10 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-8 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: gcc @@ -54,9 +58,10 @@ matrix: apt: sources: - ubuntu-toolchain-r-test + - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-8 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -65,10 +70,11 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 + - llvm-toolchain-trusty-3.7 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-3.7 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -78,9 +84,10 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-4.0 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-4.0 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -90,9 +97,10 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-5.0 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-5.0 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -102,9 +110,10 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-6.0 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-6.0 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -114,9 +123,10 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-7 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-7 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -126,9 +136,10 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-8 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-8 - - libboost-all-dev + - libboost - os: linux language: cpp compiler: clang @@ -138,10 +149,11 @@ matrix: sources: - ubuntu-toolchain-r-test - llvm-toolchain-trusty-8 + - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-8 - g++-8 - - libboost-all-dev + - libboost - os: osx language: cpp compiler: clang @@ -151,11 +163,11 @@ script: - | if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then mkdir -p cmake - travis_retry wget "https://cmake.org/files/v3.11/cmake-3.11.2-Linux-x86_64.tar.gz" - tar xf cmake-3.11.2-Linux-x86_64.tar.gz -C cmake --strip-components=1 + 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 + brew upgrade cmake boost fi - cmake --version - mkdir build From 5dfa88a1b3a4819e805588e194bbcec6c87c3471 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:13:16 +0900 Subject: [PATCH 105/162] ci: rename package to be installed --- .travis.yml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4fcca8b..a0bfbe7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-5 - - libboost + - boost1.70 - os: linux language: cpp compiler: gcc @@ -25,7 +25,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-6 - - libboost + - boost1.70 - os: linux language: cpp compiler: gcc @@ -37,7 +37,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-7 - - libboost + - boost1.70 - os: linux language: cpp compiler: gcc @@ -49,7 +49,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-8 - - libboost + - boost1.70 - os: linux language: cpp compiler: gcc @@ -61,7 +61,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - g++-8 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -74,7 +74,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-3.7 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -87,7 +87,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-4.0 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -100,7 +100,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-5.0 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -113,7 +113,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-6.0 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -126,7 +126,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-7 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -139,7 +139,7 @@ matrix: - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-8 - - libboost + - boost1.70 - os: linux language: cpp compiler: clang @@ -153,7 +153,7 @@ matrix: packages: - clang-8 - g++-8 - - libboost + - boost1.70 - os: osx language: cpp compiler: clang From dd2238e1adbad560c8845b29918330b9487103d8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:21:06 +0900 Subject: [PATCH 106/162] ci: change apt source on travis clang 3.7 trusty version seems to be restricted. I don't know why, but precise version seems to be working. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a0bfbe7..276708b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,7 @@ matrix: apt: sources: - ubuntu-toolchain-r-test - - llvm-toolchain-trusty-3.7 + - llvm-toolchain-precise-3.7 - sourceline: 'ppa:mhier/libboost-latest' packages: - clang-3.7 From 295e9bb79529df3e27ed0f28b6bcf679dccdc736 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:24:12 +0900 Subject: [PATCH 107/162] ci: try to update system library --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 276708b..be4a1a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -73,6 +73,7 @@ matrix: - llvm-toolchain-precise-3.7 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-3.7 - boost1.70 - os: linux @@ -86,6 +87,7 @@ matrix: - llvm-toolchain-trusty-4.0 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-4.0 - boost1.70 - os: linux @@ -99,6 +101,7 @@ matrix: - llvm-toolchain-trusty-5.0 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-5.0 - boost1.70 - os: linux @@ -112,6 +115,7 @@ matrix: - llvm-toolchain-trusty-6.0 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-6.0 - boost1.70 - os: linux @@ -125,6 +129,7 @@ matrix: - llvm-toolchain-trusty-7 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-7 - boost1.70 - os: linux @@ -138,6 +143,7 @@ matrix: - llvm-toolchain-trusty-8 - sourceline: 'ppa:mhier/libboost-latest' packages: + - g++-8 - clang-8 - boost1.70 - os: linux From 092db507008361bb5793de516d36ee7410e49a44 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:43:57 +0900 Subject: [PATCH 108/162] ci: use libstdc++ when compiling because some of the earlier versions of libc++ does not conform c++11 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index be4a1a4..51f2e2f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -179,6 +179,6 @@ script: - mkdir build - cd build - git clone https://github.com/toml-lang/toml.git -- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD .. +- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libstdc++" .. - make - ctest --output-on-failure From 0e2e4a26be05f5878163bc667b1165e18ed72cab Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:48:17 +0900 Subject: [PATCH 109/162] ci: Revert "ci: use libstdc++ when compiling" Ok, it already worked without this. This reverts commit 092db507008361bb5793de516d36ee7410e49a44. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 51f2e2f..be4a1a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -179,6 +179,6 @@ script: - mkdir build - cd build - git clone https://github.com/toml-lang/toml.git -- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libstdc++" .. +- cmake -DCMAKE_CXX_COMPILER=$COMPILER -DCMAKE_CXX_STANDARD=$CXX_STANDARD .. - make - ctest --output-on-failure From 9e6d8e76d0ed519860840bdbfed942120589ad82 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 20:56:49 +0900 Subject: [PATCH 110/162] fix: replace null deref by terminate for safety Since empty_iterator never points anything, so it always points null (it returns nullptr by operator->). but dereferencing null causes UB. Just calling std::terminate is of course better. --- toml/comments.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/toml/comments.hpp b/toml/comments.hpp index 97ab610..98f36c8 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -81,7 +81,10 @@ struct preserve_comments void assign(std::initializer_list 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, const std::string& x) + { + return comments.insert(p, x); + } iterator insert(const_iterator p, std::string&& x) { return comments.insert(p, std::move(x)); @@ -210,7 +213,7 @@ struct empty_iterator empty_iterator& operator=(empty_iterator &&) = default; // DO NOT call these operators. - reference_type operator*() const noexcept {return *pointer_type(nullptr);} + reference_type operator*() const noexcept {std::terminate();} pointer_type operator->() const noexcept {return nullptr;} reference_type operator[](difference_type) const noexcept {return this->operator*();} From f689d26294084e5c016bffc3165a58e81d7fed80 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 22:25:40 +0900 Subject: [PATCH 111/162] refactor: add conversion function to utf8 encoder --- toml/parser.hpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index 2d1d283..1b76503 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -253,6 +253,11 @@ std::string read_utf8_codepoint(const region& reg, std::istringstream iss(str); iss >> std::hex >> codepoint; + const auto to_char = [](const int i) noexcept -> char { + const auto uc = static_cast(i); + return *reinterpret_cast(std::addressof(uc)); + }; + std::string character; if(codepoint < 0x80) // U+0000 ... U+0079 ; just an ASCII. { @@ -261,8 +266,8 @@ std::string read_utf8_codepoint(const region& reg, else if(codepoint < 0x800) //U+0080 ... U+07FF { // 110yyyyx 10xxxxxx; 0x3f == 0b0011'1111 - character += static_cast(0xC0| codepoint >> 6); - character += static_cast(0x80|(codepoint & 0x3F)); + character += to_char(0xC0| codepoint >> 6); + character += to_char(0x80|(codepoint & 0x3F)); } else if(codepoint < 0x10000) // U+0800...U+FFFF { @@ -276,17 +281,17 @@ std::string read_utf8_codepoint(const region& reg, } assert(codepoint < 0xD800 || 0xDFFF < codepoint); // 1110yyyy 10yxxxxx 10xxxxxx - character += static_cast(0xE0| codepoint >> 12); - character += static_cast(0x80|(codepoint >> 6 & 0x3F)); - character += static_cast(0x80|(codepoint & 0x3F)); + character += to_char(0xE0| codepoint >> 12); + character += to_char(0x80|(codepoint >> 6 & 0x3F)); + character += to_char(0x80|(codepoint & 0x3F)); } else if(codepoint < 0x110000) // U+010000 ... U+10FFFF { // 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx - character += static_cast(0xF0| codepoint >> 18); - character += static_cast(0x80|(codepoint >> 12 & 0x3F)); - character += static_cast(0x80|(codepoint >> 6 & 0x3F)); - character += static_cast(0x80|(codepoint & 0x3F)); + character += to_char(0xF0| codepoint >> 18); + character += to_char(0x80|(codepoint >> 12 & 0x3F)); + character += to_char(0x80|(codepoint >> 6 & 0x3F)); + character += to_char(0x80|(codepoint & 0x3F)); } else // out of UTF-8 region { From 8208bbf236773b5ace1c946968409895196dd515 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 22:27:16 +0900 Subject: [PATCH 112/162] fix: check and convert value manually I totally have no idea when std::count returns a negative value, but the result type of `std::count` is a differnce_type. So when it is added with size_t value, implicit sign conversion happens. This changes check this kind of (almost trivial but required) checking. --- toml/region.hpp | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/toml/region.hpp b/toml/region.hpp index e6a7e68..1aaa45f 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -69,8 +69,9 @@ struct region_base template struct location final : public region_base { - using const_iterator = typename Container::const_iterator; - using source_ptr = std::shared_ptr; + using const_iterator = typename Container::const_iterator; + using difference_type = typename const_iterator::difference_type; + using source_ptr = std::shared_ptr; static_assert(std::is_same::value,""); static_assert(std::is_sameline_number_ += std::count(this->iter_, this->iter_ + n, '\n'); + this->line_number_ += static_cast( + std::count(this->iter_, std::next(this->iter_, n), '\n')); this->iter_ += n; return; } - void retrace(std::size_t n = 1) noexcept + void retrace(difference_type n = 1) noexcept { - this->line_number_ -= std::count(this->iter_ - n, this->iter_, '\n'); + this->line_number_ -= static_cast( + std::count(std::prev(this->iter_, n), this->iter_, '\n')); this->iter_ -= n; return; } @@ -121,11 +124,13 @@ struct location final : public region_base // iterators and returns a negative value if `first > last`. if(0 <= std::distance(rollback, this->iter_)) // rollback < iter { - this->line_number_ -= std::count(rollback, this->iter_, '\n'); + this->line_number_ -= static_cast( + std::count(rollback, this->iter_, '\n')); } else // iter < rollback [[unlikely]] { - this->line_number_ += std::count(this->iter_, rollback, '\n'); + this->line_number_ += static_cast( + std::count(this->iter_, rollback, '\n')); } this->iter_ = rollback; return; @@ -162,11 +167,15 @@ struct location final : public region_base } std::size_t before() const noexcept override { - return std::distance(this->line_begin(), this->iter()); + const auto sz = std::distance(this->line_begin(), this->iter()); + assert(sz >= 0); + return static_cast(sz); } std::size_t after() const noexcept override { - return std::distance(this->iter(), this->line_end()); + const auto sz = std::distance(this->iter(), this->line_end()); + assert(sz >= 0); + return static_cast(sz); } source_ptr const& source() const& noexcept {return source_;} @@ -250,15 +259,21 @@ struct region final : public region_base 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(sz); } 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(sz); } 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(sz); } bool contain_newline() const noexcept From 71ff54e76cfa387b235cb47d0d78ef45b1918305 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 23:57:40 +0900 Subject: [PATCH 113/162] fix: rearrange internal int types in datetimes --- toml/datetime.hpp | 8 ++++---- toml/parser.hpp | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/toml/datetime.hpp b/toml/datetime.hpp index f0ae405..4ea75e7 100644 --- a/toml/datetime.hpp +++ b/toml/datetime.hpp @@ -46,7 +46,7 @@ inline std::tm localtime_s(const std::time_t* src) #endif } // detail -enum class month_t : std::int8_t +enum class month_t : std::uint8_t { Jan = 0, Feb = 1, @@ -98,9 +98,9 @@ struct local_date t.tm_sec = 0; t.tm_min = 0; t.tm_hour = 0; - t.tm_mday = this->day; - t.tm_mon = this->month; - t.tm_year = this->year - 1900; + t.tm_mday = static_cast(this->day); + t.tm_mon = static_cast(this->month); + t.tm_year = static_cast(this->year) - 1900; t.tm_wday = 0; // the value will be ignored t.tm_yday = 0; // the value will be ignored t.tm_isdst = -1; diff --git a/toml/parser.hpp b/toml/parser.hpp index 1b76503..8e8a7ef 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -660,9 +660,9 @@ parse_local_time(location& loc) {{std::addressof(inner_loc), "here"}})); } local_time time( - static_cast(from_string(h.unwrap().str(), 0)), - static_cast(from_string(m.unwrap().str(), 0)), - static_cast(from_string(s.unwrap().str(), 0)), 0, 0); + from_string(h.unwrap().str(), 0), + from_string(m.unwrap().str(), 0), + from_string(s.unwrap().str(), 0), 0, 0); const auto before_secfrac = inner_loc.iter(); if(const auto secfrac = lex_time_secfrac::invoke(inner_loc)) @@ -678,13 +678,13 @@ parse_local_time(location& loc) } if(sf.size() >= 6) { - time.millisecond = from_string(sf.substr(0, 3), 0); - time.microsecond = from_string(sf.substr(3, 3), 0); + time.millisecond = from_string(sf.substr(0, 3), 0u); + time.microsecond = from_string(sf.substr(3, 3), 0u); } else if(sf.size() >= 3) { - time.millisecond = from_string(sf, 0); - time.microsecond = 0; + time.millisecond = from_string(sf, 0u); + time.microsecond = 0u; } } else From 427706d671994d8cd23798c7ad4d910f0d4b2cbd Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 23:58:15 +0900 Subject: [PATCH 114/162] fix: explicitly add float conversion --- toml/value.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 52d7b43..c0ee601 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -509,7 +509,7 @@ class basic_value : type_(value_t::floating), region_info_(std::make_shared(region_base{})) { - assigner(this->floating_, f); + assigner(this->floating_, static_cast(f)); } template>(std::move(reg))), comments_(region_info_->comments()) { - assigner(this->floating_, f); + assigner(this->floating_, static_cast(f)); } templatecleanup(); this->type_ = value_t::floating; this->region_info_ = std::make_shared(region_base{}); - assigner(this->floating_, f); + assigner(this->floating_, static_cast(f)); return *this; } From be04bf1302ab58401cb96331399cd27ab6787c45 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 23:58:35 +0900 Subject: [PATCH 115/162] refactor: convert file size to size_t --- toml/parser.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index 8e8a7ef..a7cf57e 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1939,7 +1939,8 @@ parse(std::istream& is, const std::string& fname = "unknown file") is.seekg(beg); // read whole file as a sequence of char - std::vector letters(fsize); + assert(fsize >= 0); + std::vector letters(static_cast(fsize)); is.read(letters.data(), fsize); detail::location> From be2d2aec524a1a3819cec1b85243a5d79fceb3e2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 23:59:16 +0900 Subject: [PATCH 116/162] refactor: explicitly convert difference_t to size_t --- toml/serializer.hpp | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index cba2923..6a508a6 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -29,7 +29,7 @@ struct serializer using array_type = typename value_type::array_type ; using table_type = typename value_type::table_type ; - serializer(const std::size_t w = 80, + serializer(const std::size_t w = 80u, const int float_prec = std::numeric_limits::max_digits10, const bool can_be_inlined = false, std::vector ks = {}) @@ -50,7 +50,8 @@ struct serializer { const auto fmt = "%.*g"; const auto bsz = std::snprintf(nullptr, 0, fmt, this->float_prec_, f); - std::vector buf(bsz + 1, '\0'); // +1 for null character(\0) + // +1 for null character(\0) + std::vector buf(static_cast(bsz + 1), '\0'); std::snprintf(buf.data(), buf.size(), fmt, this->float_prec_, f); std::string token(buf.begin(), std::prev(buf.end())); @@ -58,16 +59,27 @@ struct serializer { token += '0'; } - const auto e = std::find_if(token.cbegin(), token.cend(), - [](const char c) -> bool { - return c == 'E' || c == 'e'; + + const auto e = std::find_if( + token.cbegin(), token.cend(), [](const char c) noexcept -> bool { + return c == 'e' || c == 'E'; }); - if(e == token.cend()) + 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. + // 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; @@ -81,7 +93,8 @@ struct serializer { const auto offset = std::distance(token.cbegin(), e) + (sign_exists ? 2 : 1); - token.erase(offset, zero_prefix); + token.erase(static_cast(offset), + zero_prefix); } return token; } @@ -609,7 +622,7 @@ struct serializer template class M, template class V> std::string -format(const basic_value& v, std::size_t w = 80, +format(const basic_value& v, std::size_t w = 80u, int fprec = std::numeric_limits::max_digits10, bool force_inline = false) { @@ -638,8 +651,8 @@ std::basic_ostream& operator<<(std::basic_ostream& os, const basic_value& v) { // get status of std::setw(). - const std::size_t w = os.width(); - const int fprec = os.precision(); + const auto w = static_cast(os.width()); + const int fprec = os.precision(); os.width(0); if(!v.comments().empty()) From 3b71f806524961c33d8f27af889d8aee90c56155 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Thu, 20 Jun 2019 23:59:54 +0900 Subject: [PATCH 117/162] refactor: streamsize is a signed integer --- tests/test_parse_file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index e2d499b..518a98c 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) // 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(), table.size()); + ofs.write(table.data(), static_cast(table.size())); } const auto data = toml::parse("tmp.toml"); From ecf55f86d6451eed6b79618a2303111ba7ee345c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 00:25:21 +0900 Subject: [PATCH 118/162] refactor: add explicit type conversion --- toml/datetime.hpp | 12 ++++++------ toml/region.hpp | 9 +++++---- toml/serializer.hpp | 2 +- toml/source_location.hpp | 6 +++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/toml/datetime.hpp b/toml/datetime.hpp index 4ea75e7..dc52396 100644 --- a/toml/datetime.hpp +++ b/toml/datetime.hpp @@ -188,22 +188,22 @@ struct local_time explicit local_time(const std::chrono::duration& t) { const auto h = std::chrono::duration_cast(t); - this->hour = h.count(); + this->hour = static_cast(h.count()); const auto t2 = t - h; const auto m = std::chrono::duration_cast(t2); - this->minute = m.count(); + this->minute = static_cast(m.count()); const auto t3 = t2 - m; const auto s = std::chrono::duration_cast(t3); - this->second = s.count(); + this->second = static_cast(s.count()); const auto t4 = t3 - s; const auto ms = std::chrono::duration_cast(t4); - this->millisecond = ms.count(); + this->millisecond = static_cast(ms.count()); const auto t5 = t4 - ms; const auto us = std::chrono::duration_cast(t5); - this->microsecond = us.count(); + this->microsecond = static_cast(us.count()); const auto t6 = t5 - us; const auto ns = std::chrono::duration_cast(t6); - this->nanosecond = ns.count(); + this->nanosecond = static_cast(ns.count()); } operator std::chrono::nanoseconds() const diff --git a/toml/region.hpp b/toml/region.hpp index 1aaa45f..65c6818 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -424,13 +424,14 @@ inline std::string format_underline(const std::string& message, { assert(!reg_com.empty()); - const auto line_num_width = std::max_element(reg_com.begin(), reg_com.end(), + const auto line_num_width = static_cast(std::max_element( + reg_com.begin(), reg_com.end(), [](std::pair const& lhs, std::pair const& rhs) { return lhs.first->line_num().size() < rhs.first->line_num().size(); } - )->first->line_num().size(); + )->first->line_num().size()); std::ostringstream retval; retval << message << '\n'; @@ -453,7 +454,7 @@ inline std::string format_underline(const std::string& message, retval << ' ' << std::setw(line_num_width) << reg->line_num(); retval << " | " << reg->line() << '\n'; - retval << make_string(line_num_width + 1, ' '); + retval << make_string(static_cast(line_num_width + 1), ' '); retval << " | " << make_string(reg->before(), ' '); if(reg->size() == 1) @@ -477,7 +478,7 @@ inline std::string format_underline(const std::string& message, if(!helps.empty()) { retval << '\n'; - retval << make_string(line_num_width + 1, ' '); + retval << make_string(static_cast(line_num_width + 1), ' '); retval << " | "; for(const auto help : helps) { diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 6a508a6..4711236 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -652,7 +652,7 @@ operator<<(std::basic_ostream& os, const basic_value& v) { // get status of std::setw(). const auto w = static_cast(os.width()); - const int fprec = os.precision(); + const int fprec = static_cast(os.precision()); os.width(0); if(!v.comments().empty()) diff --git a/toml/source_location.hpp b/toml/source_location.hpp index 48396a0..051f4e5 100644 --- a/toml/source_location.hpp +++ b/toml/source_location.hpp @@ -48,9 +48,9 @@ struct source_location { if(reg) { - line_num_ = std::stoul(reg->line_num()); - column_num_ = reg->before() + 1; - region_size_ = reg->size(); + line_num_ = static_cast(std::stoul(reg->line_num())); + column_num_ = static_cast(reg->before() + 1); + region_size_ = static_cast(reg->size()); file_name_ = reg->name(); line_str_ = reg->line(); } From ec839bbd7521acbaa77f03770f79f238bf24aca3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 00:29:45 +0900 Subject: [PATCH 119/162] chore: add -Wextra when compiling tests --- tests/CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ef5eed5..903272d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,13 +33,16 @@ set(TEST_NAMES 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) if(COMPILER_SUPPORTS_WALL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") endif() - +if(COMPILER_SUPPORTS_WEXTRA) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") +endif() if(COMPILER_SUPPORTS_WPEDANTIC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") endif() From a68543a8956d3d74ec87f56e61b4332eae9e11c6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 13:10:02 +0900 Subject: [PATCH 120/162] fix: detect comment in stricter way --- toml/region.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/region.hpp b/toml/region.hpp index e6a7e68..b6ac6e8 100644 --- a/toml/region.hpp +++ b/toml/region.hpp @@ -382,7 +382,7 @@ struct region final : public region_base // 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 == ']'; + return !(c == ' ' || c == '\t' || c == ','); })) { // unwrap the first '#' by std::next. From 3ef8bddb6d27d5164e8954ffc62eac616ed47f9c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 13:23:15 +0900 Subject: [PATCH 121/162] doc: update README --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9748bf4..c67772e 100644 --- a/README.md +++ b/README.md @@ -792,12 +792,7 @@ std::vector vec{1,2,3,4,5}; toml::value v = vec; ``` - - -```cpp -toml::value v = vec; -``` - +All the elements of `initializer_list` should be convertible into `toml::value`. ## Preserving comments @@ -864,10 +859,14 @@ a = [ # this is not a comment for a. this will be ignored. ] # this is a comment for a. ``` -You can also append comments. The interfaces are the same as `std::vector`. +You can also append and modify comments. +The interfaces are the same as `std::vector`. ```cpp -v.comments().push_back(" add new comment."); +toml::basic_value v(42); +v.comments().push_back(" add this comment."); +// # add this comment. +// i = 42 ``` When `toml::discard_comments` is chosen, comments will not be contained in a value. From d4afed5bbb3ec69da2086483a3add9f50ebf0505 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:26:05 +0900 Subject: [PATCH 122/162] feat: construct value with a list of comments --- toml/value.hpp | 280 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 277 insertions(+), 3 deletions(-) diff --git a/toml/value.hpp b/toml/value.hpp index 52d7b43..86fc51d 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -365,6 +365,48 @@ class basic_value return *this; } + // overwrite comments ---------------------------------------------------- + + basic_value(const basic_value& v, std::vector comments) + : type_(v.type()), region_info_(v.region_info_), + comments_(std::move(comments)) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : assigner(array_ , v.array_ ); break; + case value_t::table : assigner(table_ , v.table_ ); break; + default: break; + } + } + + basic_value(basic_value&& v, std::vector comments) + : type_(v.type()), region_info_(std::move(v.region_info_)), + comments_(std::move(comments)) + { + switch(this->type_) // here this->type_ is already initialized + { + case value_t::boolean : assigner(boolean_ , std::move(v.boolean_ )); break; + case value_t::integer : assigner(integer_ , std::move(v.integer_ )); break; + case value_t::floating : assigner(floating_ , std::move(v.floating_ )); break; + case value_t::string : assigner(string_ , std::move(v.string_ )); break; + case value_t::offset_datetime: assigner(offset_datetime_, std::move(v.offset_datetime_)); break; + case value_t::local_datetime : assigner(local_datetime_ , std::move(v.local_datetime_ )); break; + case value_t::local_date : assigner(local_date_ , std::move(v.local_date_ )); break; + case value_t::local_time : assigner(local_time_ , std::move(v.local_time_ )); break; + case value_t::array : assigner(array_ , std::move(v.array_ )); break; + case value_t::table : assigner(table_ , std::move(v.table_ )); break; + default: break; + } + } + // ----------------------------------------------------------------------- // conversion between different basic_values. template class T, + template class A> + basic_value(const basic_value& v, std::vector comments) + : type_(v.type()), region_info_(v.region_info_), + comments_(std::move(comments)) + { + switch(v.type()) + { + case value_t::boolean : assigner(boolean_ , v.boolean_ ); break; + case value_t::integer : assigner(integer_ , v.integer_ ); break; + case value_t::floating : assigner(floating_ , v.floating_ ); break; + case value_t::string : assigner(string_ , v.string_ ); break; + case value_t::offset_datetime: assigner(offset_datetime_, v.offset_datetime_); break; + case value_t::local_datetime : assigner(local_datetime_ , v.local_datetime_ ); break; + case value_t::local_date : assigner(local_date_ , v.local_date_ ); break; + case value_t::local_time : assigner(local_time_ , v.local_time_ ); break; + case value_t::array : + { + array_type tmp(v.as_array(std::nothrow).begin(), + v.as_array(std::nothrow).end()); + assigner(array_, std::move(tmp)); + break; + } + case value_t::table : + { + table_type tmp(v.as_table(std::nothrow).begin(), + v.as_table(std::nothrow).end()); + assigner(table_, std::move(tmp)); + break; + } + default: break; + } + } template class T, template class A> @@ -445,7 +521,6 @@ class basic_value { assigner(this->boolean_, b); } - basic_value& operator=(boolean b) { this->cleanup(); @@ -454,7 +529,6 @@ class basic_value assigner(this->boolean_, b); return *this; } - template basic_value(boolean b, detail::region reg) : type_(value_t::boolean), @@ -463,6 +537,13 @@ class basic_value { assigner(this->boolean_, b); } + basic_value(boolean b, std::vector comments) + : type_(value_t::boolean), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->boolean_, b); + } // integer ============================================================== @@ -501,6 +582,17 @@ class basic_value return *this; } + template, detail::negation>>::value, + std::nullptr_t>::type = nullptr> + basic_value(T i, std::vector comments) + : type_(value_t::integer), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->integer_, static_cast(i)); + } + // floating ============================================================= template::value, std::nullptr_t>::type = nullptr> + basic_value(T f, std::vector comments) + : type_(value_t::floating), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->floating_, f); + } + // string =============================================================== basic_value(toml::string s) @@ -557,6 +659,13 @@ class basic_value assigner(this->string_, s); return *this; } + basic_value(toml::string s, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, std::move(s)); + } basic_value(std::string s) : type_(value_t::string), @@ -578,6 +687,20 @@ class basic_value { assigner(this->string_, toml::string(std::move(s), kind)); } + basic_value(std::string s, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(std::move(s))); + } + basic_value(std::string s, string_t kind, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(std::move(s), kind)); + } basic_value(const char* s) : type_(value_t::string), @@ -599,6 +722,20 @@ class basic_value { assigner(this->string_, toml::string(std::string(s), kind)); } + basic_value(const char* s, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(std::string(s))); + } + basic_value(const char* s, string_t kind, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(std::string(s), kind)); + } #if __cplusplus >= 201703L basic_value(std::string_view s) @@ -615,12 +752,26 @@ class basic_value assigner(this->string_, toml::string(s)); return *this; } + basic_value(std::string_view s, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(s)); + } basic_value(std::string_view s, string_t kind) : type_(value_t::string), region_info_(std::make_shared(region_base{})) { assigner(this->string_, toml::string(s, kind)); } + basic_value(std::string_view s, string_t kind, std::vector comments) + : type_(value_t::string), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->string_, toml::string(s, kind)); + } #endif // local date =========================================================== @@ -647,6 +798,13 @@ class basic_value assigner(this->local_date_, ld); return *this; } + basic_value(const local_date& ld, std::vector comments) + : type_(value_t::local_date), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->local_date_, ld); + } // local time =========================================================== @@ -664,6 +822,13 @@ class basic_value { assigner(this->local_time_, lt); } + basic_value(const local_time& lt, std::vector comments) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->local_time_, lt); + } basic_value& operator=(const local_time& lt) { this->cleanup(); @@ -672,6 +837,7 @@ class basic_value assigner(this->local_time_, lt); return *this; } + template basic_value(const std::chrono::duration& dur) : type_(value_t::local_time), @@ -680,6 +846,15 @@ class basic_value assigner(this->local_time_, local_time(dur)); } template + basic_value(const std::chrono::duration& dur, + std::vector comments) + : type_(value_t::local_time), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->local_time_, local_time(dur)); + } + template basic_value& operator=(const std::chrono::duration& dur) { this->cleanup(); @@ -705,6 +880,13 @@ class basic_value { assigner(this->local_datetime_, ldt); } + basic_value(const local_datetime& ldt, std::vector comments) + : type_(value_t::local_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->local_datetime_, ldt); + } basic_value& operator=(const local_datetime& ldt) { this->cleanup(); @@ -730,6 +912,13 @@ class basic_value { assigner(this->offset_datetime_, odt); } + basic_value(const offset_datetime& odt, std::vector comments) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->offset_datetime_, odt); + } basic_value& operator=(const offset_datetime& odt) { this->cleanup(); @@ -744,6 +933,14 @@ class basic_value { assigner(this->offset_datetime_, offset_datetime(tp)); } + basic_value(const std::chrono::system_clock::time_point& tp, + std::vector comments) + : type_(value_t::offset_datetime), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->offset_datetime_, offset_datetime(tp)); + } basic_value& operator=(const std::chrono::system_clock::time_point& tp) { this->cleanup(); @@ -769,6 +966,13 @@ class basic_value { assigner(this->array_, ary); } + basic_value(const array_type& ary, std::vector comments) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->array_, ary); + } basic_value& operator=(const array_type& ary) { this->cleanup(); @@ -778,6 +982,8 @@ class basic_value return *this; } + // array (initializer_list) ---------------------------------------------- + template::value, std::nullptr_t>::type = nullptr> @@ -788,6 +994,17 @@ class basic_value array_type ary(list.begin(), list.end()); assigner(this->array_, std::move(ary)); } + template::value, + std::nullptr_t>::type = nullptr> + basic_value(std::initializer_list list, std::vector comments) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + array_type ary(list.begin(), list.end()); + assigner(this->array_, std::move(ary)); + } template::value, std::nullptr_t>::type = nullptr> @@ -802,6 +1019,8 @@ class basic_value return *this; } + // array (STL Containers) ------------------------------------------------ + template>, detail::is_container @@ -817,6 +1036,22 @@ class basic_value std::copy(list.begin(), list.end(), ary.begin()); assigner(this->array_, std::move(ary)); } + template>, + detail::is_container + >::value, std::nullptr_t>::type = nullptr> + basic_value(const T& list, std::vector comments) + : type_(value_t::array), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + static_assert(std::is_convertible::value, + "elements of a container should be convertible to toml::value"); + + array_type ary(list.size()); + std::copy(list.begin(), list.end(), ary.begin()); + assigner(this->array_, std::move(ary)); + } template>, detail::is_container @@ -852,6 +1087,13 @@ class basic_value { assigner(this->table_, tab); } + basic_value(const table_type& tab, std::vector comments) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + assigner(this->table_, tab); + } basic_value& operator=(const table_type& tab) { this->cleanup(); @@ -871,6 +1113,17 @@ class basic_value for(const auto& elem : list) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); } + + basic_value(std::initializer_list> list, + std::vector comments) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + table_type tab; + for(const auto& elem : list) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } basic_value& operator=(std::initializer_list> list) { this->cleanup(); @@ -897,6 +1150,19 @@ class basic_value for(const auto& elem : mp) {tab[elem.first] = elem.second;} assigner(this->table_, std::move(tab)); } + template>, + detail::is_map + >::value, std::nullptr_t>::type = nullptr> + basic_value(const Map& mp, std::vector comments) + : type_(value_t::table), + region_info_(std::make_shared(region_base{})), + comments_(std::move(comments)) + { + table_type tab; + for(const auto& elem : mp) {tab[elem.first] = elem.second;} + assigner(this->table_, std::move(tab)); + } template>, detail::is_map @@ -921,6 +1187,11 @@ class basic_value detail::has_into_toml_method::value, std::nullptr_t>::type = nullptr> basic_value(const T& ud): basic_value(ud.into_toml()) {} + template::value, std::nullptr_t>::type = nullptr> + basic_value(const T& ud, std::vector comments) + : basic_value(ud.into_toml(), std::move(comments)) + {} template::value, std::nullptr_t>::type = nullptr> basic_value& operator=(const T& ud) @@ -933,7 +1204,10 @@ class basic_value template)> basic_value(const T& ud): basic_value(::toml::into::into_toml(ud)) {} - + template)> + basic_value(const T& ud, std::vector comments) + : basic_value(::toml::into::into_toml(ud), std::move(comments)) + {} template)> basic_value& operator=(const T& ud) { From e8d535e485204514fdb7b7e7de80102dd8a3e466 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:26:49 +0900 Subject: [PATCH 123/162] test: add tests for constructors with comments --- tests/test_comments.cpp | 364 +++++++++++++++++++++++++++++++++++----- 1 file changed, 325 insertions(+), 39 deletions(-) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index bf4b200..f528a63 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -23,10 +23,10 @@ BOOST_AUTO_TEST_CASE(test_comment_before) const auto& a = toml::find(v, "a"); const auto& b = toml::find(v, "b"); - BOOST_CHECK_EQUAL(a.comments().size(), 1u); - BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); - BOOST_CHECK_EQUAL(b.comments().size(), 1u); - BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for 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"( @@ -44,18 +44,17 @@ BOOST_AUTO_TEST_CASE(test_comment_before) const auto& a = toml::find(v, "a"); const auto& b = toml::find(v, "b"); - BOOST_CHECK_EQUAL(a.comments().size(), 2u); - BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); - BOOST_CHECK_EQUAL(a.comments().back(), u8" another comment for a."); - BOOST_CHECK_EQUAL(b.comments().size(), 2u); - BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); - BOOST_CHECK_EQUAL(b.comments().back(), u8" also comment for 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) { - using namespace toml::literals::toml_literals; { const std::string file = u8R"( a = 42 # comment for a. @@ -68,10 +67,10 @@ BOOST_AUTO_TEST_CASE(test_comment_inline) const auto& a = toml::find(v, "a"); const auto& b = toml::find(v, "b"); - BOOST_CHECK_EQUAL(a.comments().size(), 1u); - BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); - BOOST_CHECK_EQUAL(b.comments().size(), 1u); - BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for 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"( @@ -90,19 +89,17 @@ BOOST_AUTO_TEST_CASE(test_comment_inline) const auto& b = toml::find(v, "b"); const auto& b0 = b.as_array().at(0); - BOOST_CHECK_EQUAL(a.comments().size(), 1u); - BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); - BOOST_CHECK_EQUAL(b.comments().size(), 1u); - BOOST_CHECK_EQUAL(b.comments().front(), u8" this is a comment for b."); - BOOST_CHECK_EQUAL(b0.comments().size(), 1u); - BOOST_CHECK_EQUAL(b0.comments().front(), - u8" this is not a comment for b, but \"bar\""); + 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) { - using namespace toml::literals::toml_literals; { const std::string file = u8R"( # comment for a. @@ -124,20 +121,20 @@ BOOST_AUTO_TEST_CASE(test_comment_both) const auto& c = toml::find(v, "c"); const auto& c0 = c.as_array().at(0); - BOOST_CHECK_EQUAL(a.comments().size(), 2u); - BOOST_CHECK_EQUAL(a.comments().front(), u8" comment for a."); - BOOST_CHECK_EQUAL(a.comments().back(), u8" inline comment for a."); - BOOST_CHECK_EQUAL(b.comments().size(), 2u); - BOOST_CHECK_EQUAL(b.comments().front(), u8" comment for b."); - BOOST_CHECK_EQUAL(b.comments().back(), u8" inline comment for b."); + 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_CHECK_EQUAL(c.comments().size(), 2u); - BOOST_CHECK_EQUAL(c.comments().front(), u8" comment for c."); - BOOST_CHECK_EQUAL(c.comments().back(), u8" another comment for c."); + 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_CHECK_EQUAL(c0.comments().size(), 2u); - BOOST_CHECK_EQUAL(c0.comments().front(), u8" comment for the first element."); - BOOST_CHECK_EQUAL(c0.comments().back(), u8" this also."); + 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."); } } @@ -163,9 +160,298 @@ BOOST_AUTO_TEST_CASE(test_discard_comment) const auto& c = toml::find(v, "c"); const auto& c0 = c.as_array().at(0); - BOOST_CHECK(a.comments().empty()); - BOOST_CHECK(b.comments().empty()); - BOOST_CHECK(c.comments().empty()); - BOOST_CHECK(c0.comments().empty()); + 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; + { + const value_type v(true, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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(odt); + const value_type v(systp, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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 typename value_type::array_type a{1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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 a = {1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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 a = {1,2,3,4,5}; + const value_type v(a, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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() == 2); + 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> t{ + {"key1", 42}, {"key2", "foobar"} + }; + const value_type v(t, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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 t{ + {"key1", 42}, {"key2", "foobar"} + }; + const value_type v(t, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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; + { + const value_type v(42, {"comment1", "comment2"}); + BOOST_TEST(v.comments().size() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 2); + 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() == 0); + BOOST_TEST(u.is_integer()); + BOOST_TEST(u.as_integer() == 42); + } +} From ab1ef63da6eab4acc2b7186a7e6fbeaa828b5a0f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:31:28 +0900 Subject: [PATCH 124/162] doc: add value ctor with comments to README --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index c67772e..cdd997f 100644 --- a/README.md +++ b/README.md @@ -869,9 +869,20 @@ v.comments().push_back(" add this comment."); // i = 42 ``` +Also, you can pass a `std::vector` when constructing a +`toml::basic_value`. + +```cpp +std::vector comments{"comment 1", "comment 2"}; +const toml::basic_value v1(42, std::move(comments)); +const toml::basic_value v2(42, {"comment 1", "comment 2"}); +``` + When `toml::discard_comments` is chosen, comments will not be contained in a value. `value::comments()` will always be kept empty. All the modification on comments would be ignored. +All the element access in a `discard_comments` causes the same error as accessing +an element of an empty `std::vector`. The comments will also be serialized. If comments exist, those comments will be added just before the values. From 9f69ffa99333c2b4be7b033d58c79bc1f509c1e5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:42:44 +0900 Subject: [PATCH 125/162] fix: add unsigned symbol to integer literals --- tests/test_comments.cpp | 56 ++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index f528a63..0601587 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -171,7 +171,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) using value_type = toml::basic_value; { const value_type v(true, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -187,7 +187,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(3.14, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(toml::string("str"), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(std::string("str"), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const value_type v(std::string("str"), toml::string_t::literal, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v("str", {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -229,7 +229,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const value_type v("str", toml::string_t::literal, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { using namespace std::literals::string_view_literals; const value_type v("str"sv, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) using namespace std::literals::string_view_literals; const value_type v("str"sv, toml::string_t::literal, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -262,7 +262,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) const toml::offset_datetime odt{ld, lt, toml::time_offset{9, 0}}; { const value_type v(ld, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -270,7 +270,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(lt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const toml::local_time three_hours{3,0,0}; const value_type v(std::chrono::hours(3), {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(ldt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) } { const value_type v(odt, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -304,7 +304,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const auto systp = static_cast(odt); const value_type v(systp, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -313,7 +313,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const typename value_type::array_type a{1,2,3,4,5}; const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -331,7 +331,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const std::initializer_list a = {1,2,3,4,5}; const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) { const std::vector a = {1,2,3,4,5}; const value_type v(a, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) {"key1", 42}, {"key2", "foobar"} }; const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -383,7 +383,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) {"key1", 42}, {"key2", "foobar"} }; const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -397,7 +397,7 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) {"key1", 42}, {"key2", "foobar"} }; const value_type v(t, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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()); @@ -413,14 +413,14 @@ BOOST_AUTO_TEST_CASE(test_overwrite_comments) using value_type = toml::basic_value; { const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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() == 2); + 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()); @@ -428,14 +428,14 @@ BOOST_AUTO_TEST_CASE(test_overwrite_comments) } { const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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() == 2); + 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()); @@ -443,14 +443,14 @@ BOOST_AUTO_TEST_CASE(test_overwrite_comments) } { const value_type v(42, {"comment1", "comment2"}); - BOOST_TEST(v.comments().size() == 2); + 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() == 0); + BOOST_TEST(u.comments().size() == 0u); BOOST_TEST(u.is_integer()); BOOST_TEST(u.as_integer() == 42); } From 1694f7451022d1d876d67aac9c2a8dcb5aae2601 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:43:13 +0900 Subject: [PATCH 126/162] chore: update boost test library usage (v2->v3) --- tests/test_datetime.cpp | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/tests/test_datetime.cpp b/tests/test_datetime.cpp index ae5ae51..395949e 100644 --- a/tests/test_datetime.cpp +++ b/tests/test_datetime.cpp @@ -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 date1(date); - BOOST_CHECK_EQUAL(date, date1); + BOOST_TEST(date == date1); const std::chrono::system_clock::time_point tp(date); 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); - BOOST_CHECK(date > date3); + BOOST_TEST(date > date3); std::ostringstream oss; 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) { const toml::local_time time(12, 30, 45); const toml::local_time time1(time); - BOOST_CHECK_EQUAL(time, time1); + BOOST_TEST(time == time1); const std::chrono::nanoseconds dur(time); std::chrono::nanoseconds ns(0); ns += std::chrono::hours (12); ns += std::chrono::minutes(30); 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); - BOOST_CHECK(time > time3); + BOOST_TEST(time > time3); { std::ostringstream oss; 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); std::ostringstream oss; 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 time1(time); - BOOST_CHECK_EQUAL(time, time1); + BOOST_TEST(time == time1); const std::chrono::minutes dur(time); std::chrono::minutes m(0); m += std::chrono::hours (9); 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); - BOOST_CHECK(time2 < time); + BOOST_TEST(time2 < time); std::ostringstream oss; 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) @@ -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), toml::local_time(12, 30, 45)); 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 toml::local_datetime dt2(tp); - BOOST_CHECK_EQUAL(dt, dt2); + BOOST_TEST(dt == dt2); std::ostringstream oss; 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) @@ -97,17 +97,18 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime) toml::local_time(12, 30, 45), toml::time_offset(9, 30)); 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 toml::offset_datetime dt2(tp1); 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; 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( @@ -116,6 +117,6 @@ BOOST_AUTO_TEST_CASE(test_offset_datetime) toml::time_offset(0, 0)); std::ostringstream oss; 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")); } } From 713b42e5893d73380497c28ce22e2efaffee6bb4 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:47:27 +0900 Subject: [PATCH 127/162] refactor: use CHECK_THROW macro to check it throws --- tests/test_error_detection.cpp | 122 +++------------------------------ 1 file changed, 10 insertions(+), 112 deletions(-) diff --git a/tests/test_error_detection.cpp b/tests/test_error_detection.cpp index da6b71f..c936209 100644 --- a/tests/test_error_detection.cpp +++ b/tests/test_error_detection.cpp @@ -12,50 +12,19 @@ BOOST_AUTO_TEST_CASE(test_detect_empty_key) { std::istringstream stream(std::string("= \"value\"")); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_empty_key"); - } - catch(const toml::syntax_error& syn) - { - // to see the error message - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_missing_value) { std::istringstream stream(std::string("a =")); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_missing_value"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + 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\"")); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_too_many_value"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_duplicate_table) @@ -66,17 +35,7 @@ BOOST_AUTO_TEST_CASE(test_detect_duplicate_table) "[table]\n" "b = 42\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_duplicate_table"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_conflict_array_table) @@ -87,17 +46,7 @@ BOOST_AUTO_TEST_CASE(test_detect_conflict_array_table) "[table]\n" "b = 42\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_conflict_array_table"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_conflict_table_array) @@ -108,17 +57,7 @@ BOOST_AUTO_TEST_CASE(test_detect_conflict_table_array) "[[table]]\n" "b = 42\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_conflict_table_array"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_duplicate_value) @@ -127,17 +66,7 @@ BOOST_AUTO_TEST_CASE(test_detect_duplicate_value) "a = 1\n" "a = 2\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_duplicate_value"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_conflicting_value) @@ -146,17 +75,7 @@ BOOST_AUTO_TEST_CASE(test_detect_conflicting_value) "a.b = 1\n" "a.b.c = 2\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_conflicting_value"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array) @@ -164,17 +83,7 @@ BOOST_AUTO_TEST_CASE(test_detect_inhomogeneous_array) std::istringstream stream(std::string( "a = [1, 1.0]\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_inhomogeneous_array"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } BOOST_AUTO_TEST_CASE(test_detect_appending_array_of_table) @@ -184,16 +93,5 @@ BOOST_AUTO_TEST_CASE(test_detect_appending_array_of_table) "[[a]]\n" "b = 2\n" )); - bool exception_thrown = false; - try - { - toml::parse(stream, "test_detect_appending_array_of_table"); - } - catch(const toml::syntax_error& syn) - { - std::cerr << syn.what() << std::endl; - exception_thrown = true; - } - BOOST_CHECK(exception_thrown); + BOOST_CHECK_THROW(toml::parse(stream), toml::syntax_error); } - From 7b37d876ae66a4433a4650361c3203b7087e6edf Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:50:17 +0900 Subject: [PATCH 128/162] refactor: update Boost.Test v2 to v3 --- tests/test_extended_conversions.cpp | 145 ++++++++++++++-------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/tests/test_extended_conversions.cpp b/tests/test_extended_conversions.cpp index 2b2f430..99adeea 100644 --- a/tests/test_extended_conversions.cpp +++ b/tests/test_extended_conversions.cpp @@ -115,24 +115,23 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods) const toml::value v{{"a", 42}, {"b", "baz"}}; const auto foo = toml::get(v); - BOOST_CHECK_EQUAL(foo.a, 42); - BOOST_CHECK_EQUAL(foo.b, "baz"); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); const toml::value v2(foo); - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } { const toml::value v{{"a", 42}, {"b", "baz"}}; const auto foo = toml::get(v); - BOOST_CHECK_EQUAL(foo.a, 42); - BOOST_CHECK_EQUAL(foo.b, "baz"); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); const toml::value v2(foo); - - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } { @@ -140,13 +139,13 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_member_methods) v{{"a", 42}, {"b", "baz"}}; const auto foo = toml::get(v); - BOOST_CHECK_EQUAL(foo.a, 42); - BOOST_CHECK_EQUAL(foo.b, "baz"); + BOOST_TEST(foo.a == 42); + BOOST_TEST(foo.b == "baz"); const toml::basic_value v2(foo); - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } } @@ -156,36 +155,36 @@ BOOST_AUTO_TEST_CASE(test_conversion_by_specialization) const toml::value v{{"a", 42}, {"b", "baz"}}; const auto bar = toml::get(v); - BOOST_CHECK_EQUAL(bar.a, 42); - BOOST_CHECK_EQUAL(bar.b, "baz"); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); const toml::value v2(bar); - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } { const toml::value v{{"a", 42}, {"b", "baz"}}; const auto bar = toml::get(v); - BOOST_CHECK_EQUAL(bar.a, 42); - BOOST_CHECK_EQUAL(bar.b, "baz"); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); const toml::value v2(bar); - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } { const toml::basic_value v{{"a", 42}, {"b", "baz"}}; const auto bar = toml::get(v); - BOOST_CHECK_EQUAL(bar.a, 42); - BOOST_CHECK_EQUAL(bar.b, "baz"); + BOOST_TEST(bar.a == 42); + BOOST_TEST(bar.b == "baz"); const toml::basic_value v2(bar); - BOOST_CHECK_EQUAL(v, v2); + BOOST_TEST(v == v2); } } @@ -200,28 +199,28 @@ BOOST_AUTO_TEST_CASE(test_recursive_conversion) }; const auto foos = toml::get>(v); - BOOST_CHECK_EQUAL(foos.size() , 4ul); - BOOST_CHECK_EQUAL(foos.at(0).a , 42); - BOOST_CHECK_EQUAL(foos.at(1).a , 43); - BOOST_CHECK_EQUAL(foos.at(2).a , 44); - BOOST_CHECK_EQUAL(foos.at(3).a , 45); + 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_CHECK_EQUAL(foos.at(0).b , "baz"); - BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); - BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); - BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + 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>(v); - BOOST_CHECK_EQUAL(bars.size() , 4ul); - BOOST_CHECK_EQUAL(bars.at(0).a , 42); - BOOST_CHECK_EQUAL(bars.at(1).a , 43); - BOOST_CHECK_EQUAL(bars.at(2).a , 44); - BOOST_CHECK_EQUAL(bars.at(3).a , 45); + 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_CHECK_EQUAL(bars.at(0).b , "baz"); - BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); - BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); - BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + 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{ @@ -232,28 +231,28 @@ BOOST_AUTO_TEST_CASE(test_recursive_conversion) }; const auto foos = toml::get>(v); - BOOST_CHECK_EQUAL(foos.size() , 4ul); - BOOST_CHECK_EQUAL(foos.at(0).a , 42); - BOOST_CHECK_EQUAL(foos.at(1).a , 43); - BOOST_CHECK_EQUAL(foos.at(2).a , 44); - BOOST_CHECK_EQUAL(foos.at(3).a , 45); + 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_CHECK_EQUAL(foos.at(0).b , "baz"); - BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); - BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); - BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + 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>(v); - BOOST_CHECK_EQUAL(bars.size() , 4ul); - BOOST_CHECK_EQUAL(bars.at(0).a , 42); - BOOST_CHECK_EQUAL(bars.at(1).a , 43); - BOOST_CHECK_EQUAL(bars.at(2).a , 44); - BOOST_CHECK_EQUAL(bars.at(3).a , 45); + 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_CHECK_EQUAL(bars.at(0).b , "baz"); - BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); - BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); - BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + 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"); } { @@ -266,28 +265,28 @@ BOOST_AUTO_TEST_CASE(test_recursive_conversion) }; const auto foos = toml::get>(v); - BOOST_CHECK_EQUAL(foos.size() , 4ul); - BOOST_CHECK_EQUAL(foos.at(0).a , 42); - BOOST_CHECK_EQUAL(foos.at(1).a , 43); - BOOST_CHECK_EQUAL(foos.at(2).a , 44); - BOOST_CHECK_EQUAL(foos.at(3).a , 45); + 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_CHECK_EQUAL(foos.at(0).b , "baz"); - BOOST_CHECK_EQUAL(foos.at(1).b , "qux"); - BOOST_CHECK_EQUAL(foos.at(2).b , "quux"); - BOOST_CHECK_EQUAL(foos.at(3).b , "foobar"); + 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>(v); - BOOST_CHECK_EQUAL(bars.size() , 4ul); - BOOST_CHECK_EQUAL(bars.at(0).a , 42); - BOOST_CHECK_EQUAL(bars.at(1).a , 43); - BOOST_CHECK_EQUAL(bars.at(2).a , 44); - BOOST_CHECK_EQUAL(bars.at(3).a , 45); + 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_CHECK_EQUAL(bars.at(0).b , "baz"); - BOOST_CHECK_EQUAL(bars.at(1).b , "qux"); - BOOST_CHECK_EQUAL(bars.at(2).b , "quux"); - BOOST_CHECK_EQUAL(bars.at(3).b , "foobar"); + 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"); } } From 4032b438c07735b880a54bf4a1ed57f54f825324 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 14:59:28 +0900 Subject: [PATCH 129/162] fix: time offset may change while conversion --- tests/test_comments.cpp | 7 +- tests/test_find.cpp | 164 ++++++++++++++++++++-------------------- 2 files changed, 88 insertions(+), 83 deletions(-) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 0601587..1852dee 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -308,7 +308,12 @@ BOOST_AUTO_TEST_CASE(test_construct_value_with_comments) 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); + + // While the conversion, the information about time offset may change. + const auto systp2 = static_cast( + 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}; diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 2ed4167..28b076c 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(test_find_throws) { // the positive control. toml::value v{{"key", 42}}; - BOOST_CHECK_EQUAL(42, toml::find(v, "key")); + BOOST_TEST(42 == toml::find(v, "key")); } } @@ -63,17 +63,17 @@ BOOST_AUTO_TEST_CASE(test_find_recursive) }} }} }; - BOOST_CHECK_EQUAL(42, toml::find(v, "a", "b", "c", "d")); + BOOST_TEST(42 == toml::find(v, "a", "b", "c", "d")); // reference that can be used to modify the content auto& num = toml::find(v, "a", "b", "c", "d"); num = 54; - BOOST_CHECK_EQUAL(54, toml::find(v, "a", "b", "c", "d")); + BOOST_TEST(54 == toml::find(v, "a", "b", "c", "d")); const std::string a("a"), b("b"), c("c"), d("d"); auto& num2 = toml::find(v, a, b, c, d); num2 = 42; - BOOST_CHECK_EQUAL(42, toml::find(v, a, b, c, d)); + BOOST_TEST(42 == toml::find(v, a, b, c, d)); } } @@ -81,24 +81,24 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) { { value_type v{{"key", true}}; - BOOST_CHECK_EQUAL(true, toml::find(v, "key")); + BOOST_TEST(true == toml::find(v, "key")); toml::find(v, "key") = false; - BOOST_CHECK_EQUAL(false, toml::find(v, "key")); + BOOST_TEST(false == toml::find(v, "key")); } { value_type v{{"key", 42}}; - BOOST_CHECK_EQUAL(toml::integer(42), toml::find(v, "key")); + BOOST_TEST(toml::integer(42) == toml::find(v, "key")); toml::find(v, "key") = 54; - BOOST_CHECK_EQUAL(toml::integer(54), toml::find(v, "key")); + BOOST_TEST(toml::integer(54) == toml::find(v, "key")); } { value_type v{{"key", 3.14}}; - BOOST_CHECK_EQUAL(toml::floating(3.14), toml::find(v, "key")); + BOOST_TEST(toml::floating(3.14) == toml::find(v, "key")); toml::find(v, "key") = 2.71; - BOOST_CHECK_EQUAL(toml::floating(2.71), toml::find(v, "key")); + BOOST_TEST(toml::floating(2.71) == toml::find(v, "key")); } { value_type v{{"key", "foo"}}; @@ -200,15 +200,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_integer_type, value_type, test_value_typ { { value_type v{{"key", 42}}; - BOOST_CHECK_EQUAL(int(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(short(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(char(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(unsigned(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(long(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(std::int64_t(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(std::uint64_t(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(std::int16_t(42), toml::find(v, "key")); - BOOST_CHECK_EQUAL(std::uint16_t(42), toml::find(v, "key")); + BOOST_TEST(int(42) == toml::find(v, "key")); + BOOST_TEST(short(42) == toml::find(v, "key")); + BOOST_TEST(char(42) == toml::find(v, "key")); + BOOST_TEST(unsigned(42) == toml::find(v, "key")); + BOOST_TEST(long(42) == toml::find(v, "key")); + BOOST_TEST(std::int64_t(42) == toml::find(v, "key")); + BOOST_TEST(std::uint64_t(42) == toml::find(v, "key")); + BOOST_TEST(std::int16_t(42) == toml::find(v, "key")); + BOOST_TEST(std::uint16_t(42) == toml::find(v, "key")); } } @@ -216,9 +216,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_floating_type, value_type, test_value_ty { { value_type v{{"key", 3.14}}; - BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(v, "key")); - BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(v, "key")); - BOOST_CHECK_EQUAL(static_cast(3.14), toml::find(v, "key")); + BOOST_TEST(static_cast(3.14) == toml::find(v, "key")); + BOOST_TEST(static_cast(3.14) == toml::find(v, "key")); + BOOST_TEST(static_cast(3.14) == toml::find(v, "key")); } } @@ -226,25 +226,25 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_string_type, value_type, test_value_type { { value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; - BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + BOOST_TEST("foo" == toml::find(v, "key")); toml::find(v, "key") += "bar"; - BOOST_CHECK_EQUAL("foobar", toml::find(v, "key")); + BOOST_TEST("foobar" == toml::find(v, "key")); } { value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; - BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + BOOST_TEST("foo" == toml::find(v, "key")); toml::find(v, "key") += "bar"; - BOOST_CHECK_EQUAL("foobar", toml::find(v, "key")); + BOOST_TEST("foobar" == toml::find(v, "key")); } #if __cplusplus >= 201703L { value_type v{{"key", toml::string("foo", toml::string_t::basic)}}; - BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + BOOST_TEST("foo" == toml::find(v, "key")); } { value_type v{{"key", toml::string("foo", toml::string_t::literal)}}; - BOOST_CHECK_EQUAL("foo", toml::find(v, "key")); + BOOST_TEST("foo" == toml::find(v, "key")); } #endif } @@ -257,39 +257,39 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array, value_type, test_value_types const std::list lst = toml::find>(v, "key"); const std::deque deq = toml::find>(v, "key"); - BOOST_CHECK_EQUAL(42, vec.at(0)); - BOOST_CHECK_EQUAL(54, vec.at(1)); - BOOST_CHECK_EQUAL(69, vec.at(2)); - BOOST_CHECK_EQUAL(72, vec.at(3)); + 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::const_iterator iter = lst.begin(); - BOOST_CHECK_EQUAL(static_cast(42), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(54), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(69), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(72), *(iter++)); + BOOST_TEST(static_cast(42) == *(iter++)); + BOOST_TEST(static_cast(54) == *(iter++)); + BOOST_TEST(static_cast(69) == *(iter++)); + BOOST_TEST(static_cast(72) == *(iter++)); - BOOST_CHECK_EQUAL(static_cast(42), deq.at(0)); - BOOST_CHECK_EQUAL(static_cast(54), deq.at(1)); - BOOST_CHECK_EQUAL(static_cast(69), deq.at(2)); - BOOST_CHECK_EQUAL(static_cast(72), deq.at(3)); + BOOST_TEST(static_cast(42) == deq.at(0)); + BOOST_TEST(static_cast(54) == deq.at(1)); + BOOST_TEST(static_cast(69) == deq.at(2)); + BOOST_TEST(static_cast(72) == deq.at(3)); std::array ary = toml::find>(v, "key"); - BOOST_CHECK_EQUAL(static_cast(42), ary.at(0)); - BOOST_CHECK_EQUAL(static_cast(54), ary.at(1)); - BOOST_CHECK_EQUAL(static_cast(69), ary.at(2)); - BOOST_CHECK_EQUAL(static_cast(72), ary.at(3)); + BOOST_TEST(static_cast(42) == ary.at(0)); + BOOST_TEST(static_cast(54) == ary.at(1)); + BOOST_TEST(static_cast(69) == ary.at(2)); + BOOST_TEST(static_cast(72) == ary.at(3)); std::tuple tpl = toml::find>(v, "key"); - BOOST_CHECK_EQUAL(static_cast(42), std::get<0>(tpl)); - BOOST_CHECK_EQUAL(static_cast(54), std::get<1>(tpl)); - BOOST_CHECK_EQUAL(static_cast(69), std::get<2>(tpl)); - BOOST_CHECK_EQUAL(static_cast(72), std::get<3>(tpl)); + BOOST_TEST(static_cast(42) == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); value_type p{{"key", {3.14, 2.71}}}; std::pair pr = toml::find >(p, "key"); - BOOST_CHECK_EQUAL(3.14, pr.first); - BOOST_CHECK_EQUAL(2.71, pr.second); + 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) @@ -301,26 +301,26 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_array_of_array, value_type, test_va std::pair, std::vector> p = toml::find, std::vector>>(v, "key"); - BOOST_CHECK_EQUAL(p.first.at(0), 42); - BOOST_CHECK_EQUAL(p.first.at(1), 54); - BOOST_CHECK_EQUAL(p.first.at(2), 69); - BOOST_CHECK_EQUAL(p.first.at(3), 72); + 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_CHECK_EQUAL(p.second.at(0), "foo"); - BOOST_CHECK_EQUAL(p.second.at(1), "bar"); - BOOST_CHECK_EQUAL(p.second.at(2), "baz"); + 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> t = toml::find, std::vector>>(v, "key"); - BOOST_CHECK_EQUAL(std::get<0>(t).at(0), 42); - BOOST_CHECK_EQUAL(std::get<0>(t).at(1), 54); - BOOST_CHECK_EQUAL(std::get<0>(t).at(2), 69); - BOOST_CHECK_EQUAL(std::get<0>(t).at(3), 72); + 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_CHECK_EQUAL(std::get<1>(t).at(0), "foo"); - BOOST_CHECK_EQUAL(std::get<1>(t).at(1), "bar"); - BOOST_CHECK_EQUAL(std::get<1>(t).at(2), "baz"); + 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) @@ -329,10 +329,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_table, value_type, test_value_types {"key1", 1}, {"key2", 2}, {"key3", 3}, {"key4", 4} }}}; const auto v = toml::find>(v1, "key"); - BOOST_CHECK_EQUAL(v.at("key1"), 1); - BOOST_CHECK_EQUAL(v.at("key2"), 2); - BOOST_CHECK_EQUAL(v.at("key3"), 3); - BOOST_CHECK_EQUAL(v.at("key4"), 4); + 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) @@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_date, value_type, test_value_ t.tm_sec = 0; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_CHECK_EQUAL(c, date); + BOOST_TEST(c == date); } BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_time, value_type, test_value_types) @@ -378,7 +378,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_toml_local_datetime, value_type, test_va t.tm_sec = 45; t.tm_isdst = -1; const auto c = std::mktime(&t); - BOOST_CHECK_EQUAL(c, date); + BOOST_TEST(c == date); } BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_value_types) @@ -398,12 +398,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_va const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! BOOST_CHECK(tmp); const auto tm = *tmp; - BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018); - BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); - BOOST_CHECK_EQUAL(tm.tm_mday, 1); - BOOST_CHECK_EQUAL(tm.tm_hour, 3); - BOOST_CHECK_EQUAL(tm.tm_min, 30); - BOOST_CHECK_EQUAL(tm.tm_sec, 0); + 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); } { @@ -421,12 +421,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_offset_datetime, value_type, test_va const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! BOOST_CHECK(tmp); const auto tm = *tmp; - BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018); - BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); - BOOST_CHECK_EQUAL(tm.tm_mday, 1); - BOOST_CHECK_EQUAL(tm.tm_hour, 20); - BOOST_CHECK_EQUAL(tm.tm_min, 30); - BOOST_CHECK_EQUAL(tm.tm_sec, 0); + 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); } } From dd9b04ae3b8fb140b0f76b4665cfdce4f310b1b0 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 15:00:41 +0900 Subject: [PATCH 130/162] fix: fix test case name --- tests/test_format_error.cpp | 2 +- tests/test_get.cpp | 338 ++++++++++++++++++------------------ tests/test_traits.cpp | 72 ++++---- tests/test_utility.cpp | 50 ++---- 4 files changed, 212 insertions(+), 250 deletions(-) diff --git a/tests/test_format_error.cpp b/tests/test_format_error.cpp index 23cdea5..7e6c290 100644 --- a/tests/test_format_error.cpp +++ b/tests/test_format_error.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE "test_value" +#define BOOST_TEST_MODULE "test_format_error" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST #include #else diff --git a/tests/test_get.cpp b/tests/test_get.cpp index 833c479..df4297a 100644 --- a/tests/test_get.cpp +++ b/tests/test_get.cpp @@ -5,294 +5,284 @@ #define BOOST_TEST_NO_LIB #include #endif -#include -#include +#include #include #include #include #include #include +#include #if __cplusplus >= 201703L #include #endif +using test_value_types = std::tuple< + toml::value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; -BOOST_AUTO_TEST_CASE(test_get_exact) +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_exact, value_type, test_value_types) { { - toml::value v(true); - BOOST_CHECK_EQUAL(true, toml::get(v)); + value_type v(true); + BOOST_TEST(true == toml::get(v)); toml::get(v) = false; - BOOST_CHECK_EQUAL(false, toml::get(v)); + BOOST_TEST(false == toml::get(v)); } { - toml::value v(42); - BOOST_CHECK_EQUAL(toml::integer(42), toml::get(v)); + value_type v(42); + BOOST_TEST(toml::integer(42) == toml::get(v)); toml::get(v) = 54; - BOOST_CHECK_EQUAL(toml::integer(54), toml::get(v)); + BOOST_TEST(toml::integer(54) == toml::get(v)); } { - toml::value v(3.14); - BOOST_CHECK_EQUAL(toml::floating(3.14), toml::get(v)); + value_type v(3.14); + BOOST_TEST(toml::floating(3.14) == toml::get(v)); toml::get(v) = 2.71; - BOOST_CHECK_EQUAL(toml::floating(2.71), toml::get(v)); + BOOST_TEST(toml::floating(2.71) == toml::get(v)); } { - toml::value v("foo"); - BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::basic), + value_type v("foo"); + BOOST_TEST(toml::string("foo", toml::string_t::basic) == toml::get(v)); toml::get(v).str += "bar"; - BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::basic), + BOOST_TEST(toml::string("foobar", toml::string_t::basic) == toml::get(v)); } { - toml::value v("foo", toml::string_t::literal); - BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::literal), + value_type v("foo", toml::string_t::literal); + BOOST_TEST(toml::string("foo", toml::string_t::literal) == toml::get(v)); toml::get(v).str += "bar"; - BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::literal), + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == toml::get(v)); } { toml::local_date d(2018, toml::month_t::Apr, 22); - toml::value v(d); - BOOST_CHECK(d == toml::get(v)); + value_type v(d); + BOOST_TEST(d == toml::get(v)); toml::get(v).year = 2017; d.year = 2017; - BOOST_CHECK(d == toml::get(v)); + BOOST_TEST(d == toml::get(v)); } { toml::local_time t(12, 30, 45); - toml::value v(t); - BOOST_CHECK(t == toml::get(v)); + value_type v(t); + BOOST_TEST(t == toml::get(v)); toml::get(v).hour = 9; t.hour = 9; - BOOST_CHECK(t == toml::get(v)); + BOOST_TEST(t == toml::get(v)); } { toml::local_datetime dt(toml::local_date(2018, toml::month_t::Apr, 22), toml::local_time(12, 30, 45)); - toml::value v(dt); - BOOST_CHECK(dt == toml::get(v)); + value_type v(dt); + BOOST_TEST(dt == toml::get(v)); toml::get(v).date.year = 2017; dt.date.year = 2017; - BOOST_CHECK(dt == toml::get(v)); + BOOST_TEST(dt == toml::get(v)); } { 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)); - toml::value v(dt); - BOOST_CHECK(dt == toml::get(v)); + value_type v(dt); + BOOST_TEST(dt == toml::get(v)); toml::get(v).date.year = 2017; dt.date.year = 2017; - BOOST_CHECK(dt == toml::get(v)); + BOOST_TEST(dt == toml::get(v)); } { - toml::array vec; - vec.push_back(toml::value(42)); - vec.push_back(toml::value(54)); - toml::value v(vec); - BOOST_CHECK(vec == toml::get(v)); + using array_type = typename value_type::array_type; + array_type vec; + vec.push_back(value_type(42)); + vec.push_back(value_type(54)); + value_type v(vec); + BOOST_TEST(vec == toml::get(v)); - toml::get(v).push_back(toml::value(123)); - vec.push_back(toml::value(123)); - BOOST_CHECK(vec == toml::get(v)); + toml::get(v).push_back(value_type(123)); + vec.push_back(value_type(123)); + BOOST_TEST(vec == toml::get(v)); } { - toml::table tab; - tab["key1"] = toml::value(42); - tab["key2"] = toml::value(3.14); - toml::value v(tab); - BOOST_CHECK(tab == toml::get(v)); + using table_type = typename value_type::table_type; + table_type tab; + tab["key1"] = value_type(42); + tab["key2"] = value_type(3.14); + value_type v(tab); + BOOST_TEST(tab == toml::get(v)); - toml::get(v)["key3"] = toml::value(123); - tab["key3"] = toml::value(123); - BOOST_CHECK(tab == toml::get(v)); + toml::get(v)["key3"] = value_type(123); + tab["key3"] = value_type(123); + BOOST_TEST(tab == toml::get(v)); } { - toml::value v1(42); - BOOST_CHECK(v1 == toml::get(v1)); + value_type v1(42); + BOOST_TEST(v1 == toml::get(v1)); - toml::value v2(54); - toml::get(v1) = v2; - BOOST_CHECK(v2 == toml::get(v1)); + value_type v2(54); + toml::get(v1) = v2; + BOOST_TEST(v2 == toml::get(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); - BOOST_CHECK_EQUAL(int(42), toml::get(v)); - BOOST_CHECK_EQUAL(short(42), toml::get(v)); - BOOST_CHECK_EQUAL(char(42), toml::get(v)); - BOOST_CHECK_EQUAL(unsigned(42), toml::get(v)); - BOOST_CHECK_EQUAL(long(42), toml::get(v)); - BOOST_CHECK_EQUAL(std::int64_t(42), toml::get(v)); - BOOST_CHECK_EQUAL(std::uint64_t(42), toml::get(v)); - BOOST_CHECK_EQUAL(std::int16_t(42), toml::get(v)); - BOOST_CHECK_EQUAL(std::uint16_t(42), toml::get(v)); + value_type v(42); + BOOST_TEST(int(42) == toml::get(v)); + BOOST_TEST(short(42) == toml::get(v)); + BOOST_TEST(char(42) == toml::get(v)); + BOOST_TEST(unsigned(42) == toml::get(v)); + BOOST_TEST(long(42) == toml::get(v)); + BOOST_TEST(std::int64_t(42) == toml::get(v)); + BOOST_TEST(std::uint64_t(42) == toml::get(v)); + BOOST_TEST(std::int16_t(42) == toml::get(v)); + BOOST_TEST(std::uint16_t(42) == toml::get(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); - BOOST_CHECK_EQUAL(static_cast(3.14), toml::get(v)); - BOOST_CHECK_EQUAL(static_cast(3.14), toml::get(v)); - BOOST_CHECK_EQUAL(static_cast(3.14), toml::get(v)); + value_type v(3.14); + BOOST_TEST(static_cast(3.14) == toml::get(v)); + BOOST_TEST(static_cast(3.14) == toml::get(v)); + BOOST_TEST(static_cast(3.14) == toml::get(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); - BOOST_CHECK_EQUAL("foo", toml::get(v)); + value_type v("foo", toml::string_t::basic); + BOOST_TEST("foo" == toml::get(v)); toml::get(v) += "bar"; - BOOST_CHECK_EQUAL("foobar", toml::get(v)); + BOOST_TEST("foobar" == toml::get(v)); } { - toml::value v("foo", toml::string_t::literal); - BOOST_CHECK_EQUAL("foo", toml::get(v)); + value_type v("foo", toml::string_t::literal); + BOOST_TEST("foo" == toml::get(v)); toml::get(v) += "bar"; - BOOST_CHECK_EQUAL("foobar", toml::get(v)); + BOOST_TEST("foobar" == toml::get(v)); } #if __cplusplus >= 201703L { - toml::value v("foo", toml::string_t::basic); - BOOST_CHECK_EQUAL("foo", toml::get(v)); + value_type v("foo", toml::string_t::basic); + BOOST_TEST("foo" == toml::get(v)); } { - toml::value v("foo", toml::string_t::literal); - BOOST_CHECK_EQUAL("foo", toml::get(v)); + value_type v("foo", toml::string_t::literal); + BOOST_TEST("foo" == toml::get(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)); - toml::get(v).push_back(toml::value(42)); - toml::get(v).push_back(toml::value(54)); - toml::get(v).push_back(toml::value(69)); - toml::get(v).push_back(toml::value(72)); + const value_type v{42, 54, 69, 72}; const std::vector vec = toml::get>(v); const std::list lst = toml::get>(v); const std::deque deq = toml::get>(v); - BOOST_CHECK_EQUAL(42, vec.at(0)); - BOOST_CHECK_EQUAL(54, vec.at(1)); - BOOST_CHECK_EQUAL(69, vec.at(2)); - BOOST_CHECK_EQUAL(72, vec.at(3)); + 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::const_iterator iter = lst.begin(); - BOOST_CHECK_EQUAL(static_cast(42), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(54), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(69), *(iter++)); - BOOST_CHECK_EQUAL(static_cast(72), *(iter++)); + BOOST_TEST(static_cast(42) == *(iter++)); + BOOST_TEST(static_cast(54) == *(iter++)); + BOOST_TEST(static_cast(69) == *(iter++)); + BOOST_TEST(static_cast(72) == *(iter++)); - BOOST_CHECK_EQUAL(static_cast(42), deq.at(0)); - BOOST_CHECK_EQUAL(static_cast(54), deq.at(1)); - BOOST_CHECK_EQUAL(static_cast(69), deq.at(2)); - BOOST_CHECK_EQUAL(static_cast(72), deq.at(3)); + BOOST_TEST(static_cast(42) == deq.at(0)); + BOOST_TEST(static_cast(54) == deq.at(1)); + BOOST_TEST(static_cast(69) == deq.at(2)); + BOOST_TEST(static_cast(72) == deq.at(3)); std::array ary = toml::get>(v); - BOOST_CHECK_EQUAL(static_cast(42), ary.at(0)); - BOOST_CHECK_EQUAL(static_cast(54), ary.at(1)); - BOOST_CHECK_EQUAL(static_cast(69), ary.at(2)); - BOOST_CHECK_EQUAL(static_cast(72), ary.at(3)); + BOOST_TEST(static_cast(42) == ary.at(0)); + BOOST_TEST(static_cast(54) == ary.at(1)); + BOOST_TEST(static_cast(69) == ary.at(2)); + BOOST_TEST(static_cast(72) == ary.at(3)); std::tuple tpl = toml::get>(v); - BOOST_CHECK_EQUAL(static_cast(42), std::get<0>(tpl)); - BOOST_CHECK_EQUAL(static_cast(54), std::get<1>(tpl)); - BOOST_CHECK_EQUAL(static_cast(69), std::get<2>(tpl)); - BOOST_CHECK_EQUAL(static_cast(72), std::get<3>(tpl)); + BOOST_TEST(static_cast(42) == std::get<0>(tpl)); + BOOST_TEST(static_cast(54) == std::get<1>(tpl)); + BOOST_TEST(static_cast(69) == std::get<2>(tpl)); + BOOST_TEST(static_cast(72) == std::get<3>(tpl)); - toml::value p(toml::array{}); - toml::get(p).push_back(toml::value(3.14)); - toml::get(p).push_back(toml::value(2.71)); + const value_type p{3.14, 2.71}; std::pair pr = toml::get >(p); - BOOST_CHECK_EQUAL(3.14, pr.first); - BOOST_CHECK_EQUAL(2.71, pr.second); + BOOST_TEST(3.14 == pr.first); + 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{}); - toml::get(v1).push_back(toml::value(42)); - toml::get(v1).push_back(toml::value(54)); - toml::get(v1).push_back(toml::value(69)); - toml::get(v1).push_back(toml::value(72)); - - toml::value v2(toml::array{}); - toml::get(v2).push_back(toml::value("foo")); - toml::get(v2).push_back(toml::value("bar")); - toml::get(v2).push_back(toml::value("baz")); - - toml::value v(toml::array(2)); - toml::get(v).at(0) = v1; - toml::get(v).at(1) = v2; + const value_type v1{42, 54, 69, 72}; + const value_type v2{"foo", "bar", "baz"}; + const value_type v{v1, v2}; std::pair, std::vector> p = toml::get, std::vector>>(v); - BOOST_CHECK_EQUAL(p.first.at(0), 42); - BOOST_CHECK_EQUAL(p.first.at(1), 54); - BOOST_CHECK_EQUAL(p.first.at(2), 69); - BOOST_CHECK_EQUAL(p.first.at(3), 72); + 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_CHECK_EQUAL(p.second.at(0), "foo"); - BOOST_CHECK_EQUAL(p.second.at(1), "bar"); - BOOST_CHECK_EQUAL(p.second.at(2), "baz"); + 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> t = toml::get, std::vector>>(v); - BOOST_CHECK_EQUAL(std::get<0>(t).at(0), 42); - BOOST_CHECK_EQUAL(std::get<0>(t).at(1), 54); - BOOST_CHECK_EQUAL(std::get<0>(t).at(2), 69); - BOOST_CHECK_EQUAL(std::get<0>(t).at(3), 72); + 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_CHECK_EQUAL(std::get<1>(t).at(0), "foo"); - BOOST_CHECK_EQUAL(std::get<1>(t).at(1), "bar"); - BOOST_CHECK_EQUAL(std::get<1>(t).at(2), "baz"); + 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(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}, {"key2", 2}, {"key3", 3}, {"key4", 4} - }); + }; const auto v = toml::get>(v1); - BOOST_CHECK_EQUAL(v.at("key1"), 1); - BOOST_CHECK_EQUAL(v.at("key2"), 2); - BOOST_CHECK_EQUAL(v.at("key3"), 3); - BOOST_CHECK_EQUAL(v.at("key4"), 4); + 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(test_get_toml_local_date) +BOOST_AUTO_TEST_CASE_TEMPLATE(test_get_toml_local_date, value_type, test_value_types) { - 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( toml::get(v1)); @@ -305,20 +295,22 @@ BOOST_AUTO_TEST_CASE(test_get_toml_local_date) t.tm_sec = 0; t.tm_isdst = -1; 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(v1); - BOOST_CHECK(time == std::chrono::hours(12) + - std::chrono::minutes(30) + std::chrono::seconds(45)); + const bool result = time == std::chrono::hours(12) + + 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_time{12, 30, 45})); @@ -333,13 +325,13 @@ BOOST_AUTO_TEST_CASE(test_get_toml_local_datetime) t.tm_sec = 45; t.tm_isdst = -1; 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_time{12, 30, 0}, toml::time_offset{9, 0})); @@ -351,18 +343,18 @@ BOOST_AUTO_TEST_CASE(test_get_toml_offset_datetime) // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_CHECK(tmp); + BOOST_TEST(tmp); const auto tm = *tmp; - BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018); - BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); - BOOST_CHECK_EQUAL(tm.tm_mday, 1); - BOOST_CHECK_EQUAL(tm.tm_hour, 3); - BOOST_CHECK_EQUAL(tm.tm_min, 30); - BOOST_CHECK_EQUAL(tm.tm_sec, 0); + 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); } { - toml::value v1(toml::offset_datetime( + value_type v1(toml::offset_datetime( toml::local_date{2018, toml::month_t::Apr, 1}, toml::local_time{12, 30, 0}, toml::time_offset{-8, 0})); @@ -374,14 +366,14 @@ BOOST_AUTO_TEST_CASE(test_get_toml_offset_datetime) // get time_t as gmtime (2018-04-01T03:30:00Z) const auto tmp = std::gmtime(std::addressof(timet)); // XXX not threadsafe! - BOOST_CHECK(tmp); + BOOST_TEST(tmp); const auto tm = *tmp; - BOOST_CHECK_EQUAL(tm.tm_year + 1900, 2018); - BOOST_CHECK_EQUAL(tm.tm_mon + 1, 4); - BOOST_CHECK_EQUAL(tm.tm_mday, 1); - BOOST_CHECK_EQUAL(tm.tm_hour, 20); - BOOST_CHECK_EQUAL(tm.tm_min, 30); - BOOST_CHECK_EQUAL(tm.tm_sec, 0); + 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); } } diff --git a/tests/test_traits.cpp b/tests/test_traits.cpp index 70521ea..63b8a14 100644 --- a/tests/test_traits.cpp +++ b/tests/test_traits.cpp @@ -37,48 +37,48 @@ typedef std::unordered_map std_unordered_map_type; BOOST_AUTO_TEST_CASE(test_has_xxx) { - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_iterator::value); - BOOST_CHECK(toml::detail::has_iterator::value); - BOOST_CHECK(toml::detail::has_iterator::value); - BOOST_CHECK(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator>::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator::value); + BOOST_TEST(toml::detail::has_iterator>::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_value_type::value); - BOOST_CHECK(toml::detail::has_value_type::value); - BOOST_CHECK(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type>::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type::value); + BOOST_TEST(toml::detail::has_value_type>::value); - BOOST_CHECK(toml::detail::has_key_type::value); - BOOST_CHECK(toml::detail::has_key_type::value); - BOOST_CHECK(toml::detail::has_mapped_type::value); - BOOST_CHECK(toml::detail::has_mapped_type::value); + BOOST_TEST(toml::detail::has_key_type::value); + BOOST_TEST(toml::detail::has_key_type::value); + BOOST_TEST(toml::detail::has_mapped_type::value); + BOOST_TEST(toml::detail::has_mapped_type::value); } BOOST_AUTO_TEST_CASE(test_is_xxx) { - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container::value); - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container>::value); - BOOST_CHECK(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); + BOOST_TEST(toml::detail::is_container>::value); - BOOST_CHECK(!toml::detail::is_container::value); - BOOST_CHECK(!toml::detail::is_container::value); + BOOST_TEST(!toml::detail::is_container::value); + BOOST_TEST(!toml::detail::is_container::value); - BOOST_CHECK(toml::detail::is_map::value); - BOOST_CHECK(toml::detail::is_map::value); + BOOST_TEST(toml::detail::is_map::value); + BOOST_TEST(toml::detail::is_map::value); } diff --git a/tests/test_utility.cpp b/tests/test_utility.cpp index b879c54..c4cb003 100644 --- a/tests/test_utility.cpp +++ b/tests/test_utility.cpp @@ -14,69 +14,39 @@ BOOST_AUTO_TEST_CASE(test_resize) { typedef std::vector resizable_type; typedef std::array non_resizable_type; - BOOST_CHECK(toml::detail::has_resize_method::value); - BOOST_CHECK(!toml::detail::has_resize_method::value); + BOOST_TEST(toml::detail::has_resize_method::value); + BOOST_TEST(!toml::detail::has_resize_method::value); } - { - bool thrown = false; std::vector v; - try - { - toml::resize(v, 10); - } - catch(std::exception& ex) - { - thrown = true; - } - BOOST_CHECK(!thrown); - BOOST_CHECK_EQUAL(v.size(), 10u); + toml::resize(v, 10); + BOOST_TEST(v.size() == 10u); } - { - bool thrown = false; std::array a; - try - { - toml::resize(a, 10); - } - catch(std::exception& ex) - { - thrown = true; - } - BOOST_CHECK(!thrown); - BOOST_CHECK_EQUAL(a.size(), 15u); + toml::resize(a, 10); + BOOST_TEST(a.size() == 15u); } - { - bool thrown = false; std::array a; - try - { - toml::resize(a, 20); - } - catch(std::exception& ex) - { - thrown = true; - } - BOOST_CHECK(thrown); + BOOST_CHECK_THROW(toml::resize(a, 20), std::invalid_argument); } } BOOST_AUTO_TEST_CASE(test_concat_to_string) { 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) { { const std::string str("123"); - BOOST_CHECK_EQUAL(toml::from_string(str, 0), 123); + BOOST_TEST(toml::from_string(str, 0) == 123); } { const std::string str("01"); - BOOST_CHECK_EQUAL(toml::from_string(str, 0), 1); + BOOST_TEST(toml::from_string(str, 0) == 1); } } From 90918b6d765671c48677ed5efc45c672651d294e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 15:22:46 +0900 Subject: [PATCH 131/162] test: add basic_value type to serialization tests --- tests/test_lex_aux.hpp | 23 +- tests/test_literals.cpp | 117 ++-- tests/test_parse_aux.hpp | 23 +- tests/test_parse_file.cpp | 360 +++++------ tests/test_result.cpp | 256 ++++---- tests/test_serialize_file.cpp | 114 +++- tests/test_value.cpp | 1077 +++++++++++++++++---------------- 7 files changed, 1040 insertions(+), 930 deletions(-) diff --git a/tests/test_lex_aux.hpp b/tests/test_lex_aux.hpp index 8585c38..c0d2b16 100644 --- a/tests/test_lex_aux.hpp +++ b/tests/test_lex_aux.hpp @@ -10,17 +10,17 @@ do { \ const std::string expected(expct); \ toml::detail::location loc("test", token); \ const auto result = lxr::invoke(loc); \ - BOOST_CHECK(result.is_ok()); \ + BOOST_TEST(result.is_ok()); \ if(result.is_ok()){ \ - const auto region = result.unwrap(); \ - BOOST_CHECK_EQUAL(region.str(), expected); \ - BOOST_CHECK_EQUAL(region.str().size(), expected.size()); \ - BOOST_CHECK_EQUAL(static_cast(std::distance( \ - loc.begin(), loc.iter())), region.size()); \ + const auto region = result.unwrap(); \ + BOOST_TEST(region.str() == expected); \ + BOOST_TEST(region.str().size() == expected.size()); \ + BOOST_TEST(static_cast(std::distance( \ + loc.begin(), loc.iter())) == region.size()); \ } else { \ - std::cerr << "lexer failed with input `"; \ - std::cerr << token << "`. expected `" << expected << "`\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + std::cerr << "lexer failed with input `"; \ + std::cerr << token << "`. expected `" << expected << "`\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ } \ } while(false); \ /**/ @@ -30,6 +30,7 @@ do { \ const std::string token (tkn); \ toml::detail::location loc("test", token); \ const auto result = lxr::invoke(loc); \ - BOOST_CHECK(result.is_err()); \ - BOOST_CHECK(loc.begin() == loc.iter()); \ + BOOST_TEST(result.is_err()); \ + const bool loc_same = (loc.begin() == loc.iter()); \ + BOOST_TEST(loc_same); \ } while(false); /**/ diff --git a/tests/test_literals.cpp b/tests/test_literals.cpp index 3323168..f90f598 100644 --- a/tests/test_literals.cpp +++ b/tests/test_literals.cpp @@ -19,7 +19,7 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal) b = "baz" )"_toml; - BOOST_CHECK_EQUAL(r, v); + BOOST_TEST(r == v); } { const toml::value r{ @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal) b = "baz" )"_toml; - BOOST_CHECK_EQUAL(r, v); + BOOST_TEST(r == v); } { const toml::value r{ @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(test_file_as_literal) b = "baz" )"_toml; - BOOST_CHECK_EQUAL(r, v); + BOOST_TEST(r == v); } } @@ -57,31 +57,31 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal) const toml::value v1 = u8"true"_toml; const toml::value v2 = u8"false"_toml; - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK(toml::get(v1)); - BOOST_CHECK(!toml::get(v2)); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + BOOST_TEST(toml::get(v1)); + BOOST_TEST(!toml::get(v2)); } { const toml::value v1 = u8"123_456"_toml; const toml::value v2 = u8"0b0010"_toml; const toml::value v3 = u8"0xDEADBEEF"_toml; - BOOST_CHECK(v1.is_integer()); - BOOST_CHECK(v2.is_integer()); - BOOST_CHECK(v3.is_integer()); - BOOST_CHECK_EQUAL(toml::get(v1), 123456); - BOOST_CHECK_EQUAL(toml::get(v2), 2); - BOOST_CHECK_EQUAL(toml::get(v3), 0xDEADBEEF); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); + BOOST_TEST(v3.is_integer()); + BOOST_TEST(toml::get(v1) == 123456); + BOOST_TEST(toml::get(v2) == 2); + BOOST_TEST(toml::get(v3) == 0xDEADBEEF); } { const toml::value v1 = u8"3.1415"_toml; const toml::value v2 = u8"6.02e+23"_toml; - BOOST_CHECK(v1.is_floating()); - BOOST_CHECK(v2.is_floating()); - BOOST_CHECK_CLOSE(toml::get(v1), 3.1415, 0.00001); - BOOST_CHECK_CLOSE(toml::get(v2), 6.02e23, 0.0001); + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); + BOOST_TEST(toml::get(v1) == 3.1415, boost::test_tools::tolerance(0.00001)); + BOOST_TEST(toml::get(v2) == 6.02e23, boost::test_tools::tolerance(0.0001)); } { const toml::value v1 = u8R"("foo")"_toml; @@ -89,65 +89,74 @@ BOOST_AUTO_TEST_CASE(test_value_as_literal) const toml::value v3 = u8R"("""foo""")"_toml; const toml::value v4 = u8R"('''foo''')"_toml; - BOOST_CHECK(v1.is_string()); - BOOST_CHECK(v2.is_string()); - BOOST_CHECK(v3.is_string()); - BOOST_CHECK(v4.is_string()); - BOOST_CHECK_EQUAL(toml::get(v1), "foo"); - BOOST_CHECK_EQUAL(toml::get(v2), "foo"); - BOOST_CHECK_EQUAL(toml::get(v3), "foo"); - BOOST_CHECK_EQUAL(toml::get(v4), "foo"); + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(toml::get(v1) == "foo"); + BOOST_TEST(toml::get(v2) == "foo"); + BOOST_TEST(toml::get(v3) == "foo"); + BOOST_TEST(toml::get(v4) == "foo"); } { - const toml::value v1 = u8R"([1,2,3])"_toml; - - BOOST_CHECK(v1.is_array()); - BOOST_CHECK((toml::get>(v1) == std::vector{1,2,3})); - - const toml::value v2 = u8R"([1,])"_toml; - - BOOST_CHECK(v2.is_array()); - BOOST_CHECK((toml::get>(v2) == std::vector{1})); - - const toml::value v3 = u8R"([[1,]])"_toml; - BOOST_CHECK(v3.is_array()); - BOOST_CHECK((toml::get>(toml::get(v3).front()) == std::vector{1})); - - const toml::value v4 = u8R"([[1],])"_toml; - BOOST_CHECK(v4.is_array()); - BOOST_CHECK((toml::get>(toml::get(v4).front()) == std::vector{1})); + { + const toml::value v1 = u8R"([1,2,3])"_toml; + BOOST_TEST(v1.is_array()); + const bool result = (toml::get>(v1) == std::vector{1,2,3}); + BOOST_TEST(result); + } + { + const toml::value v2 = u8R"([1,])"_toml; + BOOST_TEST(v2.is_array()); + const bool result = (toml::get>(v2) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v3 = u8R"([[1,]])"_toml; + BOOST_TEST(v3.is_array()); + const bool result = (toml::get>(toml::get(v3).front()) == std::vector{1}); + BOOST_TEST(result); + } + { + const toml::value v4 = u8R"([[1],])"_toml; + BOOST_TEST(v4.is_array()); + const bool result = (toml::get>(toml::get(v4).front()) == std::vector{1}); + BOOST_TEST(result); + } } { const toml::value v1 = u8R"({a = 42})"_toml; - BOOST_CHECK(v1.is_table()); - BOOST_CHECK((toml::get>(v1) == - std::map{{"a", 42}})); + BOOST_TEST(v1.is_table()); + const bool result = toml::get>(v1) == + std::map{{"a", 42}}; + BOOST_TEST(result); } { const toml::value v1 = u8"1979-05-27"_toml; - BOOST_CHECK(v1.is_local_date()); - BOOST_CHECK_EQUAL(toml::get(v1), - toml::local_date(1979, toml::month_t::May, 27)); + BOOST_TEST(v1.is_local_date()); + BOOST_TEST(toml::get(v1) == + toml::local_date(1979, toml::month_t::May, 27)); } { const toml::value v1 = u8"12:00:00"_toml; - BOOST_CHECK(v1.is_local_time()); - BOOST_CHECK(toml::get(v1) == std::chrono::hours(12)); + BOOST_TEST(v1.is_local_time()); + const bool result = toml::get(v1) == std::chrono::hours(12); + BOOST_TEST(result); } { const toml::value v1 = u8"1979-05-27T07:32:00"_toml; - BOOST_CHECK(v1.is_local_datetime()); - BOOST_CHECK_EQUAL(toml::get(v1), + BOOST_TEST(v1.is_local_datetime()); + BOOST_TEST(toml::get(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_CHECK(v1.is_offset_datetime()); - BOOST_CHECK_EQUAL(toml::get(v1), + BOOST_TEST(v1.is_offset_datetime()); + BOOST_TEST(toml::get(v1) == toml::offset_datetime(toml::local_date(1979, toml::month_t::May, 27), toml::local_time(7, 32, 0), toml::time_offset(0, 0))); } diff --git a/tests/test_parse_aux.hpp b/tests/test_parse_aux.hpp index 4ef9541..6702181 100644 --- a/tests/test_parse_aux.hpp +++ b/tests/test_parse_aux.hpp @@ -1,8 +1,7 @@ #include #include #include -#include -#include +#include // some of the parsers returns not only a value but also a region. #define TOML11_TEST_PARSE_EQUAL(psr, tkn, expct) \ @@ -10,13 +9,13 @@ do { \ const std::string token(tkn); \ toml::detail::location loc("test", token); \ const auto result = psr(loc); \ - BOOST_CHECK(result.is_ok()); \ + BOOST_TEST(result.is_ok()); \ if(result.is_ok()){ \ - BOOST_CHECK(result.unwrap().first == expct); \ + BOOST_TEST(result.unwrap().first == expct); \ } else { \ - std::cerr << "parser " << #psr << " failed with input `"; \ - std::cerr << token << "`.\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + std::cerr << "parser " << #psr << " failed with input `"; \ + std::cerr << token << "`.\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ } \ } while(false); \ /**/ @@ -26,13 +25,13 @@ do { \ const std::string token(tkn); \ toml::detail::location loc("test", token); \ const auto result = psr(loc); \ - BOOST_CHECK(result.is_ok()); \ + BOOST_TEST(result.is_ok()); \ if(result.is_ok()){ \ - BOOST_CHECK(result.unwrap() == expct); \ + BOOST_TEST(result.unwrap() == expct); \ } else { \ - std::cerr << "parse_value failed with input `"; \ - std::cerr << token << "`.\n"; \ - std::cerr << "reason: " << result.unwrap_err() << '\n'; \ + std::cerr << "parse_value failed with input `"; \ + std::cerr << token << "`.\n"; \ + std::cerr << "reason: " << result.unwrap_err() << '\n'; \ } \ } while(false); \ /**/ diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index 518a98c..0e8c781 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -15,67 +15,66 @@ BOOST_AUTO_TEST_CASE(test_example) { const auto data = toml::parse("toml/tests/example.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(owner, "dob"), + BOOST_TEST(toml::find(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))); } const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + const bool result = toml::find>(database, "ports") == expected_ports; + BOOST_TEST(result); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); } const auto& servers = toml::find(data, "servers"); { toml::table alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(toml::get(alpha.at("ip")), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::get(alpha.at("dc")), "eqdc10"); + BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); + BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); toml::table beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::get(beta.at("ip")), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::get(beta.at("dc")), "eqdc10"); - BOOST_CHECK_EQUAL(toml::get(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); + BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); + BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); } const auto& clients = toml::find(data, "clients"); { toml::array clients_data = toml::find(clients, "data"); + std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); + const bool result1 = toml::get>(clients_data.at(0)) == expected_name; + BOOST_TEST(reuslt1); + std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); + const bool result2 = toml::get>(clients_data.at(1)) == expected_number; + BOOST_TEST(reuslt2); + std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); + const bool result3 = toml::find>(clients, "hosts") == expected_hosts; + BOOST_TEST(reuslt3); } std::vector products = toml::find>(data, "products"); { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), - "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), - 738594937); + BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); + BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), - "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), - 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), - "gray"); + BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); + BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); + BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); } } @@ -84,66 +83,69 @@ BOOST_AUTO_TEST_CASE(test_example_stream) std::ifstream ifs("toml/tests/example.toml"); const auto data = toml::parse(ifs); - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(owner, "dob"), + BOOST_TEST(toml::find(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))); } const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + const bool result = (toml::find>(database, "ports") == expected_ports); + BOOST_TEST(result); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); } const auto& servers = toml::find(data, "servers"); { toml::table alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(toml::get(alpha.at("ip")), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::get(alpha.at("dc")), "eqdc10"); + BOOST_TEST(toml::get(alpha.at("ip")) == "10.0.0.1"); + BOOST_TEST(toml::get(alpha.at("dc")) == "eqdc10"); toml::table beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::get(beta.at("ip")), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::get(beta.at("dc")), "eqdc10"); - BOOST_CHECK_EQUAL(toml::get(beta.at("country")), "\xE4\xB8\xAD\xE5\x9B\xBD"); + BOOST_TEST(toml::get(beta.at("ip")) == "10.0.0.2"); + BOOST_TEST(toml::get(beta.at("dc")) == "eqdc10"); + BOOST_TEST(toml::get(beta.at("country")) == "\xE4\xB8\xAD\xE5\x9B\xBD"); } const auto& clients = toml::find(data, "clients"); { toml::array clients_data = toml::find(clients, "data"); std::vector expected_name{"gamma", "delta"}; - BOOST_CHECK(toml::get>(clients_data.at(0)) == - expected_name); + const bool result1 = toml::get>(clients_data.at(0)) == expected_name; + BOOST_TEST(reuslt1); + std::vector expected_number{1, 2}; - BOOST_CHECK(toml::get>(clients_data.at(1)) == - expected_number); + const bool result2 = toml::get>(clients_data.at(1)) == expected_number; + BOOST_TEST(reuslt2); + std::vector expected_hosts{"alpha", "omega"}; - BOOST_CHECK(toml::find>(clients, "hosts") == - expected_hosts); + const bool result3 = toml::find>(clients, "hosts") == expected_hosts; + BOOST_TEST(reuslt3); } std::vector products = toml::find>(data, "products"); { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); } } @@ -152,17 +154,17 @@ BOOST_AUTO_TEST_CASE(test_fruit) { const auto data = toml::parse("toml/tests/fruit.toml"); const auto blah = toml::find(toml::find(data, "fruit"), "blah"); - BOOST_CHECK_EQUAL(toml::find(blah.at(0), "name"), "apple"); - BOOST_CHECK_EQUAL(toml::find(blah.at(1), "name"), "banana"); + BOOST_TEST(toml::find(blah.at(0), "name") == "apple"); + BOOST_TEST(toml::find(blah.at(1), "name") == "banana"); { const auto physical = toml::find(blah.at(0), "physical"); - BOOST_CHECK_EQUAL(toml::find(physical, "color"), "red"); - BOOST_CHECK_EQUAL(toml::find(physical, "shape"), "round"); + BOOST_TEST(toml::find(physical, "color") == "red"); + BOOST_TEST(toml::find(physical, "shape") == "round"); } { const auto physical = toml::find(blah.at(1), "physical"); - BOOST_CHECK_EQUAL(toml::find(physical, "color"), "yellow"); - BOOST_CHECK_EQUAL(toml::find(physical, "shape"), "bent"); + BOOST_TEST(toml::find(physical, "color") == "yellow"); + BOOST_TEST(toml::find(physical, "shape") == "bent"); } } @@ -170,7 +172,7 @@ 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_CHECK_EQUAL(toml::find(the, "test_string"), + BOOST_TEST(toml::find(the, "test_string") == "You'll hate me after this - #"); const auto hard = toml::find(the, "hard"); @@ -181,13 +183,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example) "Test #11 ]proved that", "Experiment #9 was a success"}; BOOST_CHECK(toml::find>(hard, "test_array2") == expected_the_hard_test_array2); - BOOST_CHECK_EQUAL(toml::find(hard, "another_test_string"), + BOOST_TEST(toml::find(hard, "another_test_string") == " Same thing, but with a string #"); - BOOST_CHECK_EQUAL(toml::find(hard, "harder_test_string"), + BOOST_TEST(toml::find(hard, "harder_test_string") == " And when \"'s are in the string, along with # \""); const auto bit = toml::find(hard, "bit#"); - BOOST_CHECK_EQUAL(toml::find(bit, "what?"), + BOOST_TEST(toml::find(bit, "what?") == "You don't think some user won't do that?"); const std::vector expected_multi_line_array{"]"}; BOOST_CHECK(toml::find>(bit, "multi_line_array") == @@ -197,7 +199,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_comment) { const auto data = toml::parse("toml/tests/hard_example.toml"); const auto the = toml::find(data, "the"); - BOOST_CHECK_EQUAL(toml::find(the, "test_string"), + BOOST_TEST(toml::find(the, "test_string") == "You'll hate me after this - #"); const auto hard = toml::find(the, "hard"); @@ -208,13 +210,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example_comment) "Test #11 ]proved that", "Experiment #9 was a success"}; BOOST_CHECK(toml::find>(hard, "test_array2") == expected_the_hard_test_array2); - BOOST_CHECK_EQUAL(toml::find(hard, "another_test_string"), + BOOST_TEST(toml::find(hard, "another_test_string") == " Same thing, but with a string #"); - BOOST_CHECK_EQUAL(toml::find(hard, "harder_test_string"), + BOOST_TEST(toml::find(hard, "harder_test_string") == " And when \"'s are in the string, along with # \""); const auto bit = toml::find(hard, "bit#"); - BOOST_CHECK_EQUAL(toml::find(bit, "what?"), + BOOST_TEST(toml::find(bit, "what?") == "You don't think some user won't do that?"); const std::vector expected_multi_line_array{"]"}; BOOST_CHECK(toml::find>(bit, "multi_line_array") == @@ -226,49 +228,49 @@ BOOST_AUTO_TEST_CASE(test_example_preserve_comment) { const auto data = toml::parse("toml/tests/example.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(owner, "dob"), + BOOST_TEST(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + BOOST_TEST(toml::find(owner, "dob").comments().at(0) == " First class dates? Why not?"); } const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); } const auto& servers = toml::find(data, "servers"); { const auto& alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(alpha.comments().at(0), + BOOST_TEST(alpha.comments().at(0) == " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); + BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); const auto& beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); - BOOST_CHECK_EQUAL(toml::find(beta, "country"), + BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); + BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); + BOOST_TEST(toml::find(beta, "country") == "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + BOOST_TEST(toml::find(beta, "country").comments().at(0) == " This should be parsed as UTF-8"); } const auto& clients = toml::find(data, "clients"); { - BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + BOOST_TEST(toml::find(clients, "data").comments().at(0) == " just an update to make sure parsers support it"); @@ -283,23 +285,23 @@ BOOST_AUTO_TEST_CASE(test_example_preserve_comment) BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); - BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == " Line breaks are OK when inside arrays"); } std::vector products = toml::find>(data, "products"); { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); } } @@ -316,49 +318,49 @@ BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) std::deque::type> >::value, ""); - BOOST_CHECK_EQUAL(toml::find(data, "title"), "TOML Example"); + BOOST_TEST(toml::find(data, "title") == "TOML Example"); const auto& owner = toml::find(data, "owner"); { - BOOST_CHECK_EQUAL(toml::find(owner, "name"), "Tom Preston-Werner"); - BOOST_CHECK_EQUAL(toml::find(owner, "organization"), "GitHub"); - BOOST_CHECK_EQUAL(toml::find(owner, "bio"), + BOOST_TEST(toml::find(owner, "name") == "Tom Preston-Werner"); + BOOST_TEST(toml::find(owner, "organization") == "GitHub"); + BOOST_TEST(toml::find(owner, "bio") == "GitHub Cofounder & CEO\nLikes tater tots and beer."); - BOOST_CHECK_EQUAL(toml::find(owner, "dob"), + BOOST_TEST(toml::find(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_CHECK_EQUAL(toml::find(owner, "dob").comments().at(0), + BOOST_TEST(toml::find(owner, "dob").comments().at(0) == " First class dates? Why not?"); } const auto& database = toml::find(data, "database"); { - BOOST_CHECK_EQUAL(toml::find(database, "server"), "192.168.1.1"); + BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; BOOST_CHECK(toml::find>(database, "ports") == expected_ports); - BOOST_CHECK_EQUAL(toml::find(database, "connection_max"), 5000); - BOOST_CHECK_EQUAL(toml::find(database, "enabled"), true); + BOOST_TEST(toml::find(database, "connection_max") == 5000); + BOOST_TEST(toml::find(database, "enabled") == true); } const auto& servers = toml::find(data, "servers"); { const auto& alpha = toml::find(servers, "alpha"); - BOOST_CHECK_EQUAL(alpha.comments().at(0), + BOOST_TEST(alpha.comments().at(0) == " You can indent as you please. Tabs or spaces. TOML don't care."); - BOOST_CHECK_EQUAL(toml::find(alpha, "ip"), "10.0.0.1"); - BOOST_CHECK_EQUAL(toml::find(alpha, "dc"), "eqdc10"); + BOOST_TEST(toml::find(alpha, "ip") == "10.0.0.1"); + BOOST_TEST(toml::find(alpha, "dc") == "eqdc10"); const auto& beta = toml::find(servers, "beta"); - BOOST_CHECK_EQUAL(toml::find(beta, "ip"), "10.0.0.2"); - BOOST_CHECK_EQUAL(toml::find(beta, "dc"), "eqdc10"); - BOOST_CHECK_EQUAL(toml::find(beta, "country"), + BOOST_TEST(toml::find(beta, "ip") == "10.0.0.2"); + BOOST_TEST(toml::find(beta, "dc") == "eqdc10"); + BOOST_TEST(toml::find(beta, "country") == "\xE4\xB8\xAD\xE5\x9B\xBD"); - BOOST_CHECK_EQUAL(toml::find(beta, "country").comments().at(0), + BOOST_TEST(toml::find(beta, "country").comments().at(0) == " This should be parsed as UTF-8"); } const auto& clients = toml::find(data, "clients"); { - BOOST_CHECK_EQUAL(toml::find(clients, "data").comments().at(0), + BOOST_TEST(toml::find(clients, "data").comments().at(0) == " just an update to make sure parsers support it"); @@ -373,23 +375,23 @@ BOOST_AUTO_TEST_CASE(test_example_preserve_stdmap_stddeque) BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); - BOOST_CHECK_EQUAL(toml::find(clients, "hosts").comments().at(0), + BOOST_TEST(toml::find(clients, "hosts").comments().at(0) == " Line breaks are OK when inside arrays"); } std::vector products = toml::find>(data, "products"); { - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("name")), + BOOST_TEST(toml::get(products.at(0).at("name")) == "Hammer"); - BOOST_CHECK_EQUAL(toml::get(products.at(0).at("sku")), + BOOST_TEST(toml::get(products.at(0).at("sku")) == 738594937); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("name")), + BOOST_TEST(toml::get(products.at(1).at("name")) == "Nail"); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("sku")), + BOOST_TEST(toml::get(products.at(1).at("sku")) == 284758393); - BOOST_CHECK_EQUAL(toml::get(products.at(1).at("color")), + BOOST_TEST(toml::get(products.at(1).at("color")) == "gray"); } } @@ -409,8 +411,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) std::istringstream iss(table); const auto data = toml::parse(iss, "test_file_with_BOM.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -425,8 +427,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) } const auto data = toml::parse("tmp.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -438,8 +440,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) std::istringstream iss(table); const auto data = toml::parse(iss, "test_file_with_BOM_CRLF.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -457,8 +459,8 @@ BOOST_AUTO_TEST_CASE(test_file_with_BOM) } const auto data = toml::parse("tmp.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } } @@ -474,8 +476,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -487,8 +489,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_CRLF.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { @@ -501,8 +503,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -514,8 +516,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { @@ -528,8 +530,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_ws.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -541,8 +543,8 @@ BOOST_AUTO_TEST_CASE(test_file_without_newline_at_the_end_of_file) const auto data = toml::parse(iss, "test_file_without_newline_at_the_end_of_file_ws.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } } @@ -561,8 +563,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -576,8 +578,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } // comment w/ newline @@ -593,8 +595,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -608,8 +610,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } // CRLF version @@ -625,8 +627,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -640,8 +642,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -654,8 +656,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -669,8 +671,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_comment) const auto data = toml::parse(iss, "test_files_end_with_comment.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } } @@ -688,8 +690,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -703,8 +705,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } // with whitespaces @@ -720,8 +722,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -735,8 +737,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -750,8 +752,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -765,8 +767,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } // with whitespaces but no newline @@ -781,8 +783,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } @@ -799,8 +801,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -814,8 +816,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } // with whitespaces @@ -831,8 +833,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -846,8 +848,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -861,8 +863,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -876,8 +878,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } { const std::string table( @@ -890,8 +892,8 @@ BOOST_AUTO_TEST_CASE(test_files_end_with_empty_lines) const auto data = toml::parse(iss, "test_files_end_with_newline.toml"); - BOOST_CHECK_EQUAL(toml::find(data, "key"), "value"); - BOOST_CHECK_EQUAL(toml::find(toml::find(data, "table"), "key"), "value"); + BOOST_TEST(toml::find(data, "key") == "value"); + BOOST_TEST(toml::find(toml::find(data, "table"), "key") == "value"); } } diff --git a/tests/test_result.cpp b/tests/test_result.cpp index 4832c5d..d693bd6 100644 --- a/tests/test_result.cpp +++ b/tests/test_result.cpp @@ -8,49 +8,49 @@ BOOST_AUTO_TEST_CASE(test_construct) { auto s = toml::ok(42); toml::result result(s); - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { const auto s = toml::ok(42); toml::result result(s); - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { toml::result result(toml::ok(42)); - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { auto f = toml::err("foobar"); toml::result result(f); - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); } { const auto f = toml::err("foobar"); toml::result result(f); - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); } { toml::result result(toml::err("foobar")); - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "foobar"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "foobar"); } } @@ -59,54 +59,54 @@ BOOST_AUTO_TEST_CASE(test_assignment) { toml::result result(toml::err("foobar")); result = toml::ok(42); - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { toml::result result(toml::err("foobar")); auto s = toml::ok(42); result = s; - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { toml::result result(toml::err("foobar")); const auto s = toml::ok(42); result = s; - BOOST_CHECK(!!result); - BOOST_CHECK(result.is_ok()); - BOOST_CHECK(!result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap(), 42); + BOOST_TEST(!!result); + BOOST_TEST(result.is_ok()); + BOOST_TEST(!result.is_err()); + BOOST_TEST(result.unwrap() == 42); } { toml::result result(toml::err("foobar")); result = toml::err("hoge"); - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); } { toml::result result(toml::err("foobar")); auto f = toml::err("hoge"); result = f; - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); } { toml::result result(toml::err("foobar")); const auto f = toml::err("hoge"); result = f; - BOOST_CHECK(!result); - BOOST_CHECK(!result.is_ok()); - BOOST_CHECK(result.is_err()); - BOOST_CHECK_EQUAL(result.unwrap_err(), "hoge"); + BOOST_TEST(!result); + BOOST_TEST(!result.is_ok()); + BOOST_TEST(result.is_err()); + BOOST_TEST(result.unwrap_err() == "hoge"); } } @@ -119,10 +119,10 @@ BOOST_AUTO_TEST_CASE(test_map) return i * 2; }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42 * 2); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42 * 2); } { toml::result, std::string> @@ -132,10 +132,10 @@ BOOST_AUTO_TEST_CASE(test_map) return *i; }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); } { const toml::result result(toml::err("hoge")); @@ -144,10 +144,10 @@ BOOST_AUTO_TEST_CASE(test_map) return i * 2; }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); } { toml::result, std::string> @@ -157,10 +157,10 @@ BOOST_AUTO_TEST_CASE(test_map) return *i; }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); } } @@ -173,10 +173,10 @@ BOOST_AUTO_TEST_CASE(test_map_err) return s + s; }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); } { toml::result, std::string> @@ -186,10 +186,10 @@ BOOST_AUTO_TEST_CASE(test_map_err) return s + s; }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(*(mapped.unwrap()), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(*(mapped.unwrap()) == 42); } { const toml::result result(toml::err("hoge")); @@ -197,10 +197,10 @@ BOOST_AUTO_TEST_CASE(test_map_err) [](const std::string s) -> std::string { return s + s; }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); } { toml::result> @@ -210,10 +210,10 @@ BOOST_AUTO_TEST_CASE(test_map_err) return *p; }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); } } @@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else) return i * 2; }, 54); - BOOST_CHECK_EQUAL(mapped, 42 * 2); + BOOST_TEST(mapped == 42 * 2); } { toml::result, std::string> @@ -236,7 +236,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else) return *i; }, 54); - BOOST_CHECK_EQUAL(mapped, 42); + BOOST_TEST(mapped == 42); } { const toml::result result(toml::err("hoge")); @@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else) return i * 2; }, 54); - BOOST_CHECK_EQUAL(mapped, 54); + BOOST_TEST(mapped == 54); } { toml::result, std::string> @@ -255,7 +255,7 @@ BOOST_AUTO_TEST_CASE(test_map_or_else) return *i; }, 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; }, "foobar"); - BOOST_CHECK_EQUAL(mapped, "foobar"); + BOOST_TEST(mapped == "foobar"); } { toml::result, std::string> @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else) return i + i; }, "foobar"); - BOOST_CHECK_EQUAL(mapped, "foobar"); + BOOST_TEST(mapped == "foobar"); } { const toml::result result(toml::err("hoge")); @@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else) return i + i; }, "foobar"); - BOOST_CHECK_EQUAL(mapped, "hogehoge"); + BOOST_TEST(mapped == "hogehoge"); } { toml::result, std::string> @@ -297,7 +297,7 @@ BOOST_AUTO_TEST_CASE(test_map_err_or_else) return i + i; }, "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); }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42 * 2); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42 * 2); } { toml::result, std::string> @@ -324,10 +324,10 @@ BOOST_AUTO_TEST_CASE(test_and_then) return toml::ok(*i); }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); } { const toml::result result(toml::err("hoge")); @@ -336,10 +336,10 @@ BOOST_AUTO_TEST_CASE(test_and_then) return toml::ok(i * 2); }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); } { toml::result, std::string> @@ -349,10 +349,10 @@ BOOST_AUTO_TEST_CASE(test_and_then) return toml::ok(*i); }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hoge"); } } @@ -365,10 +365,10 @@ BOOST_AUTO_TEST_CASE(test_or_else) return toml::err(s + s); }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap(), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(mapped.unwrap() == 42); } { toml::result, std::string> @@ -378,10 +378,10 @@ BOOST_AUTO_TEST_CASE(test_or_else) return toml::err(s + s); }); - BOOST_CHECK(!!mapped); - BOOST_CHECK(mapped.is_ok()); - BOOST_CHECK(!mapped.is_err()); - BOOST_CHECK_EQUAL(*mapped.unwrap(), 42); + BOOST_TEST(!!mapped); + BOOST_TEST(mapped.is_ok()); + BOOST_TEST(!mapped.is_err()); + BOOST_TEST(*mapped.unwrap() == 42); } { const toml::result result(toml::err("hoge")); @@ -390,10 +390,10 @@ BOOST_AUTO_TEST_CASE(test_or_else) return toml::err(s + s); }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); } { toml::result, std::string> @@ -403,10 +403,10 @@ BOOST_AUTO_TEST_CASE(test_or_else) return toml::err(s + s); }); - BOOST_CHECK(!mapped); - BOOST_CHECK(!mapped.is_ok()); - BOOST_CHECK(mapped.is_err()); - BOOST_CHECK_EQUAL(mapped.unwrap_err(), "hogehoge"); + BOOST_TEST(!mapped); + BOOST_TEST(!mapped.is_ok()); + BOOST_TEST(mapped.is_err()); + BOOST_TEST(mapped.unwrap_err() == "hogehoge"); } } @@ -416,10 +416,10 @@ BOOST_AUTO_TEST_CASE(test_and_or_other) const toml::result r1(toml::ok(42)); const toml::result r2(toml::err("foo")); - BOOST_CHECK_EQUAL(r1, r1.or_other(r2)); - BOOST_CHECK_EQUAL(r2, r1.and_other(r2)); - BOOST_CHECK_EQUAL(42, r1.or_other(r2).unwrap()); - BOOST_CHECK_EQUAL("foo", r1.and_other(r2).unwrap_err()); + 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 { @@ -431,10 +431,10 @@ BOOST_AUTO_TEST_CASE(test_and_or_other) const auto r3 = r1_gen(); const auto r4 = r2_gen(); - BOOST_CHECK_EQUAL(r3, r1_gen().or_other (r2_gen())); - BOOST_CHECK_EQUAL(r4, r1_gen().and_other(r2_gen())); - BOOST_CHECK_EQUAL(42, r1_gen().or_other (r2_gen()).unwrap()); - BOOST_CHECK_EQUAL("foo", r1_gen().and_other(r2_gen()).unwrap_err()); + 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()); } } diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 372249b..5c963b8 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -19,15 +19,38 @@ BOOST_AUTO_TEST_CASE(test_example) auto serialized = toml::parse("tmp1.toml"); { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::get(owner.at("bio")); + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); const auto CR = std::find(bio.begin(), bio.end(), '\r'); if(CR != bio.end()) { bio.erase(CR); } } - BOOST_CHECK(data == serialized); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_example_map_dq) +{ + 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(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) @@ -40,15 +63,42 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment) auto serialized = toml::parse("tmp1_com.toml"); { - auto& owner = toml::find(serialized, "owner"); - auto& bio = toml::get(owner.at("bio")); + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); const auto CR = std::find(bio.begin(), bio.end(), '\r'); if(CR != bio.end()) { bio.erase(CR); } } - BOOST_CHECK(data == serialized); + 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/tests/example.toml"); + { + std::ofstream ofs("tmp1_com.toml"); + ofs << std::setw(80) << data; + } + + auto serialized = toml::parse( + "tmp1_com.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(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; @@ -63,7 +113,20 @@ BOOST_AUTO_TEST_CASE(test_fruit) ofs << std::setw(80) << data; } const auto serialized = toml::parse("tmp2.toml"); - BOOST_CHECK(data == serialized); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_fruit_map_dq) +{ + 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_with_comments) @@ -74,7 +137,19 @@ BOOST_AUTO_TEST_CASE(test_fruit_with_comments) ofs << std::setw(80) << data; } const auto serialized = toml::parse("tmp2_com.toml"); - BOOST_CHECK(data == serialized); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_fruit_with_comments_map_dq) +{ + const auto data = toml::parse( + "toml/tests/fruit.toml"); + { + std::ofstream ofs("tmp2_com.toml"); + ofs << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp2_com.toml"); + BOOST_TEST(data == serialized); } BOOST_AUTO_TEST_CASE(test_hard_example) @@ -85,20 +160,35 @@ BOOST_AUTO_TEST_CASE(test_hard_example) ofs << std::setw(80) << data; } const auto serialized = toml::parse("tmp3.toml"); - BOOST_CHECK(data == serialized); + BOOST_TEST(data == serialized); +} + +BOOST_AUTO_TEST_CASE(test_hard_example_map_dq) +{ + 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_with_comment) { - const auto data = toml::parse("toml/tests/hard_example.toml"); + const auto data = toml::parse( + "toml/tests/hard_example.toml"); { std::ofstream ofs("tmp3_com.toml"); ofs << std::setw(80) << data; } - const auto serialized = toml::parse("tmp3_com.toml"); + const auto serialized = toml::parse( + "tmp3_com.toml"); { std::ofstream ofs("tmp3_com1.toml"); ofs << std::setw(80) << serialized; } - BOOST_CHECK(data == serialized); + BOOST_TEST(data == serialized); } diff --git a/tests/test_value.cpp b/tests/test_value.cpp index ee0f003..a0d32c6 100644 --- a/tests/test_value.cpp +++ b/tests/test_value.cpp @@ -5,7 +5,7 @@ #define BOOST_TEST_NO_LIB #include #endif -#include +#include #include #include @@ -19,91 +19,91 @@ BOOST_AUTO_TEST_CASE(test_value_boolean) toml::value v1(true); toml::value v2(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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); - BOOST_CHECK_EQUAL(v2.as_boolean(), false); - BOOST_CHECK_EQUAL(v1.as_boolean(std::nothrow), true); - BOOST_CHECK_EQUAL(v2.as_boolean(std::nothrow), false); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); + BOOST_TEST(v1.as_boolean(std::nothrow) == true); + BOOST_TEST(v2.as_boolean(std::nothrow) == false); v1 = false; v2 = true; - 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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), false); - BOOST_CHECK_EQUAL(v2.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), false); - BOOST_CHECK_EQUAL(v2.as_boolean(), true); + BOOST_TEST(v1.cast() == false); + BOOST_TEST(v2.cast() == true); + BOOST_TEST(v1.as_boolean() == false); + BOOST_TEST(v2.as_boolean() == true); toml::value v3(v1); toml::value v4(v2); - BOOST_CHECK(v3 == v1); - BOOST_CHECK(v4 == v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::boolean); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::boolean); - BOOST_CHECK(v3.is(toml::value_t::boolean)); - BOOST_CHECK(v4.is(toml::value_t::boolean)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v3.is_boolean()); - BOOST_CHECK(v4.is_boolean()); + BOOST_TEST(v3.type() == toml::value_t::boolean); + BOOST_TEST(v4.type() == toml::value_t::boolean); + BOOST_TEST(v3.is(toml::value_t::boolean)); + BOOST_TEST(v4.is(toml::value_t::boolean)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_boolean()); + BOOST_TEST(v4.is_boolean()); - BOOST_CHECK_EQUAL(v3.cast(), false); - BOOST_CHECK_EQUAL(v4.cast(), true); - BOOST_CHECK_EQUAL(v3.as_boolean(), false); - BOOST_CHECK_EQUAL(v4.as_boolean(), true); + BOOST_TEST(v3.cast() == false); + BOOST_TEST(v4.cast() == true); + BOOST_TEST(v3.as_boolean() == false); + BOOST_TEST(v4.as_boolean() == true); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::boolean); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::boolean); - BOOST_CHECK(v5.is(toml::value_t::boolean)); - BOOST_CHECK(v6.is(toml::value_t::boolean)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); - BOOST_CHECK(v3.is_boolean()); - BOOST_CHECK(v4.is_boolean()); + BOOST_TEST(v5.type() == toml::value_t::boolean); + BOOST_TEST(v6.type() == toml::value_t::boolean); + BOOST_TEST(v5.is(toml::value_t::boolean)); + BOOST_TEST(v6.is(toml::value_t::boolean)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v3.is_boolean()); + BOOST_TEST(v4.is_boolean()); - BOOST_CHECK_EQUAL(v5.cast(), false); - BOOST_CHECK_EQUAL(v6.cast(), true); - BOOST_CHECK_EQUAL(v5.as_boolean(), false); - BOOST_CHECK_EQUAL(v6.as_boolean(), true); + BOOST_TEST(v5.cast() == false); + BOOST_TEST(v6.cast() == true); + BOOST_TEST(v5.as_boolean() == false); + BOOST_TEST(v6.as_boolean() == true); v1 = 42; v2 = 3.14; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::integer); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); - BOOST_CHECK(v1.is(toml::value_t::integer)); - BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_integer()); - BOOST_CHECK(v2.is_floating()); + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_floating()); - BOOST_CHECK_EQUAL(v1.cast(), 42); - BOOST_CHECK_EQUAL(v2.cast(), 3.14); - BOOST_CHECK_EQUAL(v1.as_integer(), 42); - BOOST_CHECK_EQUAL(v2.as_floating(), 3.14); + BOOST_TEST(v1.cast() == 42); + BOOST_TEST(v2.cast() == 3.14); + BOOST_TEST(v1.as_integer() == 42); + BOOST_TEST(v2.as_floating() == 3.14); } BOOST_AUTO_TEST_CASE(test_value_integer) @@ -111,91 +111,91 @@ BOOST_AUTO_TEST_CASE(test_value_integer) toml::value v1(-42); toml::value v2(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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_integer()); - BOOST_CHECK(v2.is_integer()); + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::integer); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::integer)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); - BOOST_CHECK_EQUAL(v1.cast(), -42); - BOOST_CHECK_EQUAL(v2.cast(), 42u); - BOOST_CHECK_EQUAL(v1.as_integer(), -42); - BOOST_CHECK_EQUAL(v2.as_integer(), 42u); - BOOST_CHECK_EQUAL(v1.as_integer(std::nothrow), -42); - BOOST_CHECK_EQUAL(v2.as_integer(std::nothrow), 42u); + BOOST_TEST(v1.cast() == -42); + BOOST_TEST(v2.cast() == 42u); + BOOST_TEST(v1.as_integer() == -42); + BOOST_TEST(v2.as_integer() == 42u); + BOOST_TEST(v1.as_integer(std::nothrow) == -42); + BOOST_TEST(v2.as_integer(std::nothrow) == 42u); v1 = 54; v2 = -54; - 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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_integer()); - BOOST_CHECK(v2.is_integer()); + BOOST_TEST(v1.type() == toml::value_t::integer); + BOOST_TEST(v2.type() == toml::value_t::integer); + BOOST_TEST(v1.is(toml::value_t::integer)); + BOOST_TEST(v2.is(toml::value_t::integer)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_integer()); + BOOST_TEST(v2.is_integer()); - BOOST_CHECK_EQUAL(v1.cast(), 54); - BOOST_CHECK_EQUAL(v2.cast(), -54); - BOOST_CHECK_EQUAL(v1.as_integer(), 54); - BOOST_CHECK_EQUAL(v2.as_integer(), -54); + BOOST_TEST(v1.cast() == 54); + BOOST_TEST(v2.cast() == -54); + BOOST_TEST(v1.as_integer() == 54); + BOOST_TEST(v2.as_integer() == -54); toml::value v3(v1); toml::value v4(v2); - BOOST_CHECK(v3 == v1); - BOOST_CHECK(v4 == v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::integer); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::integer); - BOOST_CHECK(v3.is(toml::value_t::integer)); - BOOST_CHECK(v4.is(toml::value_t::integer)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v3.is_integer()); - BOOST_CHECK(v4.is_integer()); + BOOST_TEST(v3.type() == toml::value_t::integer); + BOOST_TEST(v4.type() == toml::value_t::integer); + BOOST_TEST(v3.is(toml::value_t::integer)); + BOOST_TEST(v4.is(toml::value_t::integer)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_integer()); + BOOST_TEST(v4.is_integer()); - BOOST_CHECK_EQUAL(v3.cast(), 54); - BOOST_CHECK_EQUAL(v4.cast(), -54); - BOOST_CHECK_EQUAL(v3.as_integer(), 54); - BOOST_CHECK_EQUAL(v4.as_integer(), -54); + BOOST_TEST(v3.cast() == 54); + BOOST_TEST(v4.cast() == -54); + BOOST_TEST(v3.as_integer() == 54); + BOOST_TEST(v4.as_integer() == -54); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::integer); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::integer); - BOOST_CHECK(v5.is(toml::value_t::integer)); - BOOST_CHECK(v6.is(toml::value_t::integer)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); - BOOST_CHECK(v5.is_integer()); - BOOST_CHECK(v6.is_integer()); + BOOST_TEST(v5.type() == toml::value_t::integer); + BOOST_TEST(v6.type() == toml::value_t::integer); + BOOST_TEST(v5.is(toml::value_t::integer)); + BOOST_TEST(v6.is(toml::value_t::integer)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v5.is_integer()); + BOOST_TEST(v6.is_integer()); - BOOST_CHECK_EQUAL(v5.cast(), 54); - BOOST_CHECK_EQUAL(v6.cast(), -54); - BOOST_CHECK_EQUAL(v5.as_integer(), 54); - BOOST_CHECK_EQUAL(v6.as_integer(), -54); + BOOST_TEST(v5.cast() == 54); + BOOST_TEST(v6.cast() == -54); + BOOST_TEST(v5.as_integer() == 54); + BOOST_TEST(v6.as_integer() == -54); v1 = true; v2 = 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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); - BOOST_CHECK_EQUAL(v2.as_boolean(), false); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); } BOOST_AUTO_TEST_CASE(test_value_float) @@ -203,91 +203,100 @@ BOOST_AUTO_TEST_CASE(test_value_float) toml::value v1(3.14); toml::value v2(3.14f); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::floating); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); - BOOST_CHECK(v1.is(toml::value_t::floating)); - BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_floating()); - BOOST_CHECK(v2.is_floating()); + BOOST_TEST(v1.type() == toml::value_t::floating); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::floating)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); - BOOST_CHECK_EQUAL (v1.cast(), 3.14); - BOOST_CHECK_CLOSE_FRACTION(v2.cast(), 3.14, 1e-2); - BOOST_CHECK_EQUAL (v1.as_floating(), 3.14); - BOOST_CHECK_CLOSE_FRACTION(v2.as_floating(), 3.14, 1e-2); - BOOST_CHECK_EQUAL (v1.as_floating(std::nothrow), 3.14); - BOOST_CHECK_CLOSE_FRACTION(v2.as_floating(std::nothrow), 3.14, 1e-2); + BOOST_TEST(v1.cast() == 3.14); + BOOST_TEST(v2.cast() == 3.14, + boost::test_tools::tolerance(1e-2)); + BOOST_TEST(v1.as_floating() == 3.14); + BOOST_TEST(v2.as_floating() == 3.14, + boost::test_tools::tolerance(1e-2)); + BOOST_TEST(v1.as_floating(std::nothrow) == 3.14); + BOOST_TEST(v2.as_floating(std::nothrow) == 3.14, + boost::test_tools::tolerance(1e-2)); v1 = 2.718f; v2 = 2.718; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::floating); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::floating); - BOOST_CHECK(v1.is(toml::value_t::floating)); - BOOST_CHECK(v2.is(toml::value_t::floating)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_floating()); - BOOST_CHECK(v2.is_floating()); + BOOST_TEST(v1.type() == toml::value_t::floating); + BOOST_TEST(v2.type() == toml::value_t::floating); + BOOST_TEST(v1.is(toml::value_t::floating)); + BOOST_TEST(v2.is(toml::value_t::floating)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_floating()); + BOOST_TEST(v2.is_floating()); - BOOST_CHECK_CLOSE_FRACTION(v1.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v2.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v1.as_floating(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v2.as_floating(), 2.718); + BOOST_TEST(v1.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v2.cast() == 2.718); + BOOST_TEST(v1.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v2.as_floating() == 2.718); toml::value v3(v1); toml::value v4(v2); - BOOST_CHECK(v3 == v1); - BOOST_CHECK(v4 == v2); + BOOST_TEST(v3 == v1); + BOOST_TEST(v4 == v2); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::floating); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::floating); - BOOST_CHECK(v3.is(toml::value_t::floating)); - BOOST_CHECK(v4.is(toml::value_t::floating)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v3.is_floating()); - BOOST_CHECK(v4.is_floating()); + BOOST_TEST(v3.type() == toml::value_t::floating); + BOOST_TEST(v4.type() == toml::value_t::floating); + BOOST_TEST(v3.is(toml::value_t::floating)); + BOOST_TEST(v4.is(toml::value_t::floating)); + BOOST_TEST(v3.is()); + BOOST_TEST(v4.is()); + BOOST_TEST(v3.is_floating()); + BOOST_TEST(v4.is_floating()); - BOOST_CHECK_CLOSE_FRACTION(v3.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v4.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v3.as_floating(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v4.as_floating(), 2.718); + BOOST_TEST(v3.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v4.cast() == 2.718); + BOOST_TEST(v3.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v4.as_floating() == 2.718); toml::value v5(std::move(v1)); toml::value v6(std::move(v2)); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::floating); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::floating); - BOOST_CHECK(v5.is(toml::value_t::floating)); - BOOST_CHECK(v6.is(toml::value_t::floating)); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); - BOOST_CHECK(v5.is_floating()); - BOOST_CHECK(v6.is_floating()); + BOOST_TEST(v5.type() == toml::value_t::floating); + BOOST_TEST(v6.type() == toml::value_t::floating); + BOOST_TEST(v5.is(toml::value_t::floating)); + BOOST_TEST(v6.is(toml::value_t::floating)); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v5.is_floating()); + BOOST_TEST(v6.is_floating()); - BOOST_CHECK_CLOSE_FRACTION(v5.cast(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v6.cast(), 2.718); - BOOST_CHECK_CLOSE_FRACTION(v5.as_floating(), 2.718, 1e-3); - BOOST_CHECK_EQUAL (v6.as_floating(), 2.718); + BOOST_TEST(v5.cast() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v6.cast() == 2.718); + BOOST_TEST(v5.as_floating() == 2.718, + boost::test_tools::tolerance(1e-3)); + BOOST_TEST(v6.as_floating() == 2.718); v1 = true; v2 = 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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), false); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); - BOOST_CHECK_EQUAL(v2.as_boolean(), false); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == false); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == false); } BOOST_AUTO_TEST_CASE(test_value_string) @@ -296,123 +305,123 @@ BOOST_AUTO_TEST_CASE(test_value_string) toml::value v2(std::string("foo"), toml::string_t::literal); toml::value v3("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()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v1.is_string()); - BOOST_CHECK(v2.is_string()); - BOOST_CHECK(v3.is_string()); + BOOST_TEST(v1.type() == toml::value_t::string); + BOOST_TEST(v2.type() == toml::value_t::string); + BOOST_TEST(v3.type() == toml::value_t::string); + BOOST_TEST(v1.is(toml::value_t::string)); + BOOST_TEST(v2.is(toml::value_t::string)); + BOOST_TEST(v3.is(toml::value_t::string)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v3.is()); + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); - BOOST_CHECK_EQUAL(v1.cast(), "foo"); - BOOST_CHECK_EQUAL(v2.cast(), "foo"); - BOOST_CHECK_EQUAL(v3.cast(), "foo"); - BOOST_CHECK_EQUAL(v1.as_string(), "foo"); - BOOST_CHECK_EQUAL(v2.as_string(), "foo"); - BOOST_CHECK_EQUAL(v3.as_string(), "foo"); - BOOST_CHECK_EQUAL(v1.as_string(std::nothrow), "foo"); - BOOST_CHECK_EQUAL(v2.as_string(std::nothrow), "foo"); - BOOST_CHECK_EQUAL(v3.as_string(std::nothrow), "foo"); + BOOST_TEST(v1.cast() == "foo"); + BOOST_TEST(v2.cast() == "foo"); + BOOST_TEST(v3.cast() == "foo"); + BOOST_TEST(v1.as_string() == "foo"); + BOOST_TEST(v2.as_string() == "foo"); + BOOST_TEST(v3.as_string() == "foo"); + BOOST_TEST(v1.as_string(std::nothrow) == "foo"); + BOOST_TEST(v2.as_string(std::nothrow) == "foo"); + BOOST_TEST(v3.as_string(std::nothrow) == "foo"); v1 = "bar"; v2 = "bar"; v3 = "bar"; - 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_string()); - BOOST_CHECK(v2.is_string()); - BOOST_CHECK(v3.is_string()); + BOOST_TEST(v1.type() == toml::value_t::string); + BOOST_TEST(v2.type() == toml::value_t::string); + BOOST_TEST(v3.type() == toml::value_t::string); + BOOST_TEST(v1.is(toml::value_t::string)); + BOOST_TEST(v2.is(toml::value_t::string)); + BOOST_TEST(v3.is(toml::value_t::string)); + BOOST_TEST(v1.is_string()); + BOOST_TEST(v2.is_string()); + BOOST_TEST(v3.is_string()); - BOOST_CHECK_EQUAL(v1.cast(), "bar"); - BOOST_CHECK_EQUAL(v2.cast(), "bar"); - BOOST_CHECK_EQUAL(v3.cast(), "bar"); - BOOST_CHECK_EQUAL(v1.as_string(), "bar"); - BOOST_CHECK_EQUAL(v2.as_string(), "bar"); - BOOST_CHECK_EQUAL(v3.as_string(), "bar"); + BOOST_TEST(v1.cast() == "bar"); + BOOST_TEST(v2.cast() == "bar"); + BOOST_TEST(v3.cast() == "bar"); + BOOST_TEST(v1.as_string() == "bar"); + BOOST_TEST(v2.as_string() == "bar"); + BOOST_TEST(v3.as_string() == "bar"); toml::value v4(v1); toml::value v5(v2); toml::value v6(v3); - BOOST_CHECK(v4 == v1); - BOOST_CHECK(v5 == v2); - BOOST_CHECK(v6 == v3); + BOOST_TEST(v4 == v1); + BOOST_TEST(v5 == v2); + BOOST_TEST(v6 == v3); - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::string); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::string); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::string); - BOOST_CHECK(v4.is(toml::value_t::string)); - BOOST_CHECK(v5.is(toml::value_t::string)); - BOOST_CHECK(v6.is(toml::value_t::string)); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); - BOOST_CHECK(v4.is_string()); - BOOST_CHECK(v5.is_string()); - BOOST_CHECK(v6.is_string()); + BOOST_TEST(v4.type() == toml::value_t::string); + BOOST_TEST(v5.type() == toml::value_t::string); + BOOST_TEST(v6.type() == toml::value_t::string); + BOOST_TEST(v4.is(toml::value_t::string)); + BOOST_TEST(v5.is(toml::value_t::string)); + BOOST_TEST(v6.is(toml::value_t::string)); + BOOST_TEST(v4.is()); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); + BOOST_TEST(v6.is_string()); - BOOST_CHECK_EQUAL(v4.cast(), "bar"); - BOOST_CHECK_EQUAL(v5.cast(), "bar"); - BOOST_CHECK_EQUAL(v6.cast(), "bar"); - BOOST_CHECK_EQUAL(v4.as_string(), "bar"); - BOOST_CHECK_EQUAL(v5.as_string(), "bar"); - BOOST_CHECK_EQUAL(v6.as_string(), "bar"); + BOOST_TEST(v4.cast() == "bar"); + BOOST_TEST(v5.cast() == "bar"); + BOOST_TEST(v6.cast() == "bar"); + BOOST_TEST(v4.as_string() == "bar"); + BOOST_TEST(v5.as_string() == "bar"); + BOOST_TEST(v6.as_string() == "bar"); v4.cast().str.at(2) = 'z'; v5.cast().str.at(2) = 'z'; v6.cast().str.at(2) = 'z'; - BOOST_CHECK_EQUAL(v4.type(), toml::value_t::string); - BOOST_CHECK_EQUAL(v5.type(), toml::value_t::string); - BOOST_CHECK_EQUAL(v6.type(), toml::value_t::string); - BOOST_CHECK(v4.is(toml::value_t::string)); - BOOST_CHECK(v5.is(toml::value_t::string)); - BOOST_CHECK(v6.is(toml::value_t::string)); - BOOST_CHECK(v4.is()); - BOOST_CHECK(v5.is()); - BOOST_CHECK(v6.is()); - BOOST_CHECK(v4.is_string()); - BOOST_CHECK(v5.is_string()); - BOOST_CHECK(v6.is_string()); + BOOST_TEST(v4.type() == toml::value_t::string); + BOOST_TEST(v5.type() == toml::value_t::string); + BOOST_TEST(v6.type() == toml::value_t::string); + BOOST_TEST(v4.is(toml::value_t::string)); + BOOST_TEST(v5.is(toml::value_t::string)); + BOOST_TEST(v6.is(toml::value_t::string)); + BOOST_TEST(v4.is()); + BOOST_TEST(v5.is()); + BOOST_TEST(v6.is()); + BOOST_TEST(v4.is_string()); + BOOST_TEST(v5.is_string()); + BOOST_TEST(v6.is_string()); - BOOST_CHECK_EQUAL(v4.as_string(), "baz"); - BOOST_CHECK_EQUAL(v5.as_string(), "baz"); - BOOST_CHECK_EQUAL(v6.as_string(), "baz"); + BOOST_TEST(v4.as_string() == "baz"); + BOOST_TEST(v5.as_string() == "baz"); + BOOST_TEST(v6.as_string() == "baz"); v1 = true; v2 = true; v3 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::boolean); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v2.is(toml::value_t::boolean)); - BOOST_CHECK(v3.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK(v2.is_boolean()); - BOOST_CHECK(v3.is_boolean()); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v2.type() == toml::value_t::boolean); + BOOST_TEST(v3.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v2.is(toml::value_t::boolean)); + BOOST_TEST(v3.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v3.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v2.is_boolean()); + BOOST_TEST(v3.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v2.cast(), true); - BOOST_CHECK_EQUAL(v3.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); - BOOST_CHECK_EQUAL(v2.as_boolean(), true); - BOOST_CHECK_EQUAL(v3.as_boolean(), true); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v2.cast() == true); + BOOST_TEST(v3.cast() == true); + BOOST_TEST(v1.as_boolean() == true); + BOOST_TEST(v2.as_boolean() == true); + BOOST_TEST(v3.as_boolean() == true); #if __cplusplus >= 201703L std::string_view sv = "foo"; @@ -420,17 +429,17 @@ BOOST_AUTO_TEST_CASE(test_value_string) toml::value v7(sv); toml::value v8(sv, toml::string_t::literal); - BOOST_CHECK_EQUAL(v7.type(), toml::value_t::string); - BOOST_CHECK_EQUAL(v8.type(), toml::value_t::string); - BOOST_CHECK(v7.is(toml::value_t::string)); - BOOST_CHECK(v8.is(toml::value_t::string)); - BOOST_CHECK(v7.is()); - BOOST_CHECK(v8.is()); - BOOST_CHECK(v7.is_string()); - BOOST_CHECK(v8.is_string()); + BOOST_TEST(v7.type() == toml::value_t::string); + BOOST_TEST(v8.type() == toml::value_t::string); + BOOST_TEST(v7.is(toml::value_t::string)); + BOOST_TEST(v8.is(toml::value_t::string)); + BOOST_TEST(v7.is()); + BOOST_TEST(v8.is()); + BOOST_TEST(v7.is_string()); + BOOST_TEST(v8.is_string()); - BOOST_CHECK_EQUAL(v7.cast(), "foo"); - BOOST_CHECK_EQUAL(v8.cast(), "foo"); + BOOST_TEST(v7.cast() == "foo"); + BOOST_TEST(v8.cast() == "foo"); #endif } @@ -438,50 +447,50 @@ BOOST_AUTO_TEST_CASE(test_value_local_date) { toml::value v1(toml::local_date(2018, toml::month_t::Jan, 31)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_date); - BOOST_CHECK(v1.is(toml::value_t::local_date)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_local_date()); + BOOST_TEST(v1.type() == toml::value_t::local_date); + BOOST_TEST(v1.is(toml::value_t::local_date)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_date()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::local_date(2018, toml::month_t::Jan, 31)); - BOOST_CHECK_EQUAL(v1.as_local_date(), + BOOST_TEST(v1.as_local_date() == toml::local_date(2018, toml::month_t::Jan, 31)); - BOOST_CHECK_EQUAL(v1.as_local_date(std::nothrow), + BOOST_TEST(v1.as_local_date(std::nothrow) == toml::local_date(2018, toml::month_t::Jan, 31)); v1 = toml::local_date(2018, toml::month_t::Apr, 1); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_date); - BOOST_CHECK(v1.is(toml::value_t::local_date)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_local_date()); + BOOST_TEST(v1.type() == toml::value_t::local_date); + BOOST_TEST(v1.is(toml::value_t::local_date)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_date()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::local_date(2018, toml::month_t::Apr, 1)); - BOOST_CHECK_EQUAL(v1.as_local_date(), + BOOST_TEST(v1.as_local_date() == toml::local_date(2018, toml::month_t::Apr, 1)); toml::value v2(v1); - BOOST_CHECK(v2 == v1); + BOOST_TEST(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_date); - BOOST_CHECK(v2.is(toml::value_t::local_date)); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v2.is_local_date()); + BOOST_TEST(v2.type() == toml::value_t::local_date); + BOOST_TEST(v2.is(toml::value_t::local_date)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_local_date()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_TEST(v2.cast() == toml::local_date(2018, toml::month_t::Apr, 1)); - BOOST_CHECK_EQUAL(v2.as_local_date(), + BOOST_TEST(v2.as_local_date() == toml::local_date(2018, toml::month_t::Apr, 1)); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_local_time) @@ -490,63 +499,63 @@ BOOST_AUTO_TEST_CASE(test_value_local_time) toml::value v2(std::chrono::hours(12) + std::chrono::minutes(30) + std::chrono::seconds(45)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_time); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_time); - BOOST_CHECK(v1.is(toml::value_t::local_time)); - BOOST_CHECK(v2.is(toml::value_t::local_time)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v1.is_local_time()); - BOOST_CHECK(v2.is_local_time()); + BOOST_TEST(v1.type() == toml::value_t::local_time); + BOOST_TEST(v2.type() == toml::value_t::local_time); + BOOST_TEST(v1.is(toml::value_t::local_time)); + BOOST_TEST(v2.is(toml::value_t::local_time)); + BOOST_TEST(v1.is()); + BOOST_TEST(v2.is()); + BOOST_TEST(v1.is_local_time()); + BOOST_TEST(v2.is_local_time()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v1.as_local_time(), + BOOST_TEST(v1.as_local_time() == toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_TEST(v2.cast() == toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v2.as_local_time(), + BOOST_TEST(v2.as_local_time() == toml::local_time(12, 30, 45)); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == v2.cast()); - BOOST_CHECK_EQUAL(v1.as_local_time(), + BOOST_TEST(v1.as_local_time() == v2.as_local_time()); - BOOST_CHECK_EQUAL(v1.as_local_time(std::nothrow), + BOOST_TEST(v1.as_local_time(std::nothrow) == v2.as_local_time(std::nothrow)); v1 = toml::local_time(1, 30, 0, /*ms*/ 100, /*us*/ 0); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_time); - BOOST_CHECK(v1.is(toml::value_t::local_time)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_local_time()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.type() == toml::value_t::local_time); + BOOST_TEST(v1.is(toml::value_t::local_time)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_time()); + BOOST_TEST(v1.cast() == toml::local_time(1, 30, 0, 100, 0)); - BOOST_CHECK_EQUAL(v1.as_local_time(), + BOOST_TEST(v1.as_local_time() == toml::local_time(1, 30, 0, 100, 0)); toml::value v3(v1); - BOOST_CHECK(v3 == v1); + BOOST_TEST(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::local_time); - BOOST_CHECK(v3.is(toml::value_t::local_time)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v3.is_local_time()); + BOOST_TEST(v3.type() == toml::value_t::local_time); + BOOST_TEST(v3.is(toml::value_t::local_time)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_local_time()); - BOOST_CHECK_EQUAL(v3.cast(), + BOOST_TEST(v3.cast() == toml::local_time(1, 30, 0, 100, 0)); - BOOST_CHECK_EQUAL(v3.as_local_time(), + BOOST_TEST(v3.as_local_time() == toml::local_time(1, 30, 0, 100, 0)); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_local_datetime) @@ -556,20 +565,20 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) toml::local_time(12, 30, 45) )); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_datetime); - BOOST_CHECK(v1.is(toml::value_t::local_datetime)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_local_datetime()); + BOOST_TEST(v1.type() == toml::value_t::local_datetime); + BOOST_TEST(v1.is(toml::value_t::local_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::local_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45))); - BOOST_CHECK_EQUAL(v1.as_local_datetime(), + BOOST_TEST(v1.as_local_datetime() == toml::local_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45))); - BOOST_CHECK_EQUAL(v1.as_local_datetime(std::nothrow), + BOOST_TEST(v1.as_local_datetime(std::nothrow) == toml::local_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45))); @@ -579,45 +588,45 @@ BOOST_AUTO_TEST_CASE(test_value_local_datetime) toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::local_datetime); - BOOST_CHECK(v1.is(toml::value_t::local_datetime)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_local_datetime()); + BOOST_TEST(v1.type() == toml::value_t::local_datetime); + BOOST_TEST(v1.is(toml::value_t::local_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_local_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); - BOOST_CHECK_EQUAL(v1.as_local_datetime(), + BOOST_TEST(v1.as_local_datetime() == toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); toml::value v2(v1); - BOOST_CHECK(v2 == v1); + BOOST_TEST(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::local_datetime); - BOOST_CHECK(v2.is(toml::value_t::local_datetime)); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v2.is_local_datetime()); + BOOST_TEST(v2.type() == toml::value_t::local_datetime); + BOOST_TEST(v2.is(toml::value_t::local_datetime)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_local_datetime()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_TEST(v2.cast() == toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); - BOOST_CHECK_EQUAL(v2.as_local_datetime(), + BOOST_TEST(v2.as_local_datetime() == toml::local_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30))); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_offset_datetime) @@ -628,24 +637,24 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::time_offset(9, 0) )); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); - BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_offset_datetime()); + BOOST_TEST(v1.type() == toml::value_t::offset_datetime); + BOOST_TEST(v1.is(toml::value_t::offset_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_offset_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == 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.as_offset_datetime(), + BOOST_TEST(v1.as_offset_datetime() == 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.as_offset_datetime(std::nothrow), + BOOST_TEST(v1.as_offset_datetime(std::nothrow) == toml::offset_datetime( toml::local_date(2018, toml::month_t::Jan, 31), toml::local_time(12, 30, 45), @@ -658,17 +667,17 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::local_time(1, 15, 30), toml::time_offset(9, 0)); - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::offset_datetime); - BOOST_CHECK(v1.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_offset_datetime()); + BOOST_TEST(v1.type() == toml::value_t::offset_datetime); + BOOST_TEST(v1.is(toml::value_t::offset_datetime)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_offset_datetime()); - BOOST_CHECK_EQUAL(v1.cast(), + BOOST_TEST(v1.cast() == toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), toml::time_offset(9, 0))); - BOOST_CHECK_EQUAL(v1.as_offset_datetime(), + BOOST_TEST(v1.as_offset_datetime() == toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), @@ -676,31 +685,31 @@ BOOST_AUTO_TEST_CASE(test_value_offset_datetime) toml::value v2(v1); - BOOST_CHECK(v2 == v1); + BOOST_TEST(v2 == v1); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::offset_datetime); - BOOST_CHECK(v2.is(toml::value_t::offset_datetime)); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v2.is_offset_datetime()); + BOOST_TEST(v2.type() == toml::value_t::offset_datetime); + BOOST_TEST(v2.is(toml::value_t::offset_datetime)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_offset_datetime()); - BOOST_CHECK_EQUAL(v2.cast(), + BOOST_TEST(v2.cast() == toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), toml::time_offset(9, 0))); - BOOST_CHECK_EQUAL(v2.as_offset_datetime(), + BOOST_TEST(v2.as_offset_datetime() == toml::offset_datetime( toml::local_date(2018, toml::month_t::Apr, 1), toml::local_time(1, 15, 30), toml::time_offset(9, 0))); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_array) @@ -709,181 +718,181 @@ BOOST_AUTO_TEST_CASE(test_value_array) toml::value v1(v); toml::value v2{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()); - BOOST_CHECK(v1.is_array()); + BOOST_TEST(v1.type() == toml::value_t::array); + BOOST_TEST(v1.is(toml::value_t::array)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_array()); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); - BOOST_CHECK(v2.is(toml::value_t::array)); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v2.is_array()); + BOOST_TEST(v2.type() == toml::value_t::array); + BOOST_TEST(v2.is(toml::value_t::array)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_array()); - BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 1); - BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 2); - BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 3); - BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 4); - BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 5); - BOOST_CHECK_EQUAL(v1.as_array().at(0).as_integer(), 1); - BOOST_CHECK_EQUAL(v1.as_array().at(1).as_integer(), 2); - BOOST_CHECK_EQUAL(v1.as_array().at(2).as_integer(), 3); - BOOST_CHECK_EQUAL(v1.as_array().at(3).as_integer(), 4); - BOOST_CHECK_EQUAL(v1.as_array().at(4).as_integer(), 5); - BOOST_CHECK_EQUAL(v1.as_array(std::nothrow).at(0).as_integer(), 1); - BOOST_CHECK_EQUAL(v1.as_array(std::nothrow).at(1).as_integer(), 2); - BOOST_CHECK_EQUAL(v1.as_array(std::nothrow).at(2).as_integer(), 3); - BOOST_CHECK_EQUAL(v1.as_array(std::nothrow).at(3).as_integer(), 4); - BOOST_CHECK_EQUAL(v1.as_array(std::nothrow).at(4).as_integer(), 5); + BOOST_TEST(v1.cast().at(0).cast() == 1); + BOOST_TEST(v1.cast().at(1).cast() == 2); + BOOST_TEST(v1.cast().at(2).cast() == 3); + BOOST_TEST(v1.cast().at(3).cast() == 4); + BOOST_TEST(v1.cast().at(4).cast() == 5); + BOOST_TEST(v1.as_array().at(0).as_integer() == 1); + BOOST_TEST(v1.as_array().at(1).as_integer() == 2); + BOOST_TEST(v1.as_array().at(2).as_integer() == 3); + BOOST_TEST(v1.as_array().at(3).as_integer() == 4); + BOOST_TEST(v1.as_array().at(4).as_integer() == 5); + BOOST_TEST(v1.as_array(std::nothrow).at(0).as_integer() == 1); + BOOST_TEST(v1.as_array(std::nothrow).at(1).as_integer() == 2); + BOOST_TEST(v1.as_array(std::nothrow).at(2).as_integer() == 3); + BOOST_TEST(v1.as_array(std::nothrow).at(3).as_integer() == 4); + BOOST_TEST(v1.as_array(std::nothrow).at(4).as_integer() == 5); - BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 0); + BOOST_TEST(v2.cast().at(0).cast() == 6); + BOOST_TEST(v2.cast().at(1).cast() == 7); + BOOST_TEST(v2.cast().at(2).cast() == 8); + BOOST_TEST(v2.cast().at(3).cast() == 9); + BOOST_TEST(v2.cast().at(4).cast() == 0); v1 = {6,7,8,9,0}; v2 = v; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::array); - BOOST_CHECK(v1.is(toml::value_t::array)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_array()); + BOOST_TEST(v1.type() == toml::value_t::array); + BOOST_TEST(v1.is(toml::value_t::array)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_array()); - BOOST_CHECK_EQUAL(v2.type(), toml::value_t::array); - BOOST_CHECK(v2.is(toml::value_t::array)); - BOOST_CHECK(v2.is()); - BOOST_CHECK(v2.is_array()); + BOOST_TEST(v2.type() == toml::value_t::array); + BOOST_TEST(v2.is(toml::value_t::array)); + BOOST_TEST(v2.is()); + BOOST_TEST(v2.is_array()); - BOOST_CHECK_EQUAL(v1.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v1.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v1.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v1.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v1.cast().at(4).cast(), 0); - BOOST_CHECK_EQUAL(v1.as_array().at(0).as_integer(), 6); - BOOST_CHECK_EQUAL(v1.as_array().at(1).as_integer(), 7); - BOOST_CHECK_EQUAL(v1.as_array().at(2).as_integer(), 8); - BOOST_CHECK_EQUAL(v1.as_array().at(3).as_integer(), 9); - BOOST_CHECK_EQUAL(v1.as_array().at(4).as_integer(), 0); + BOOST_TEST(v1.cast().at(0).cast() == 6); + BOOST_TEST(v1.cast().at(1).cast() == 7); + BOOST_TEST(v1.cast().at(2).cast() == 8); + BOOST_TEST(v1.cast().at(3).cast() == 9); + BOOST_TEST(v1.cast().at(4).cast() == 0); + BOOST_TEST(v1.as_array().at(0).as_integer() == 6); + BOOST_TEST(v1.as_array().at(1).as_integer() == 7); + BOOST_TEST(v1.as_array().at(2).as_integer() == 8); + BOOST_TEST(v1.as_array().at(3).as_integer() == 9); + BOOST_TEST(v1.as_array().at(4).as_integer() == 0); - BOOST_CHECK_EQUAL(v2.cast().at(0).cast(), 1); - BOOST_CHECK_EQUAL(v2.cast().at(1).cast(), 2); - BOOST_CHECK_EQUAL(v2.cast().at(2).cast(), 3); - BOOST_CHECK_EQUAL(v2.cast().at(3).cast(), 4); - BOOST_CHECK_EQUAL(v2.cast().at(4).cast(), 5); - BOOST_CHECK_EQUAL(v2.as_array().at(0).as_integer(), 1); - BOOST_CHECK_EQUAL(v2.as_array().at(1).as_integer(), 2); - BOOST_CHECK_EQUAL(v2.as_array().at(2).as_integer(), 3); - BOOST_CHECK_EQUAL(v2.as_array().at(3).as_integer(), 4); - BOOST_CHECK_EQUAL(v2.as_array().at(4).as_integer(), 5); + BOOST_TEST(v2.cast().at(0).cast() == 1); + BOOST_TEST(v2.cast().at(1).cast() == 2); + BOOST_TEST(v2.cast().at(2).cast() == 3); + BOOST_TEST(v2.cast().at(3).cast() == 4); + BOOST_TEST(v2.cast().at(4).cast() == 5); + BOOST_TEST(v2.as_array().at(0).as_integer() == 1); + BOOST_TEST(v2.as_array().at(1).as_integer() == 2); + BOOST_TEST(v2.as_array().at(2).as_integer() == 3); + BOOST_TEST(v2.as_array().at(3).as_integer() == 4); + BOOST_TEST(v2.as_array().at(4).as_integer() == 5); toml::value v3(v1); - BOOST_CHECK(v3 == v1); + BOOST_TEST(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::array); - BOOST_CHECK(v3.is(toml::value_t::array)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v3.is_array()); + BOOST_TEST(v3.type() == toml::value_t::array); + BOOST_TEST(v3.is(toml::value_t::array)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_array()); - BOOST_CHECK_EQUAL(v3.cast().at(0).cast(), 6); - BOOST_CHECK_EQUAL(v3.cast().at(1).cast(), 7); - BOOST_CHECK_EQUAL(v3.cast().at(2).cast(), 8); - BOOST_CHECK_EQUAL(v3.cast().at(3).cast(), 9); - BOOST_CHECK_EQUAL(v3.cast().at(4).cast(), 0); - BOOST_CHECK_EQUAL(v3.as_array().at(0).as_integer(), 6); - BOOST_CHECK_EQUAL(v3.as_array().at(1).as_integer(), 7); - BOOST_CHECK_EQUAL(v3.as_array().at(2).as_integer(), 8); - BOOST_CHECK_EQUAL(v3.as_array().at(3).as_integer(), 9); - BOOST_CHECK_EQUAL(v3.as_array().at(4).as_integer(), 0); + BOOST_TEST(v3.cast().at(0).cast() == 6); + BOOST_TEST(v3.cast().at(1).cast() == 7); + BOOST_TEST(v3.cast().at(2).cast() == 8); + BOOST_TEST(v3.cast().at(3).cast() == 9); + BOOST_TEST(v3.cast().at(4).cast() == 0); + BOOST_TEST(v3.as_array().at(0).as_integer() == 6); + BOOST_TEST(v3.as_array().at(1).as_integer() == 7); + BOOST_TEST(v3.as_array().at(2).as_integer() == 8); + BOOST_TEST(v3.as_array().at(3).as_integer() == 9); + BOOST_TEST(v3.as_array().at(4).as_integer() == 0); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_table) { toml::value v1{{"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()); - BOOST_CHECK(v1.is_table()); + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); - BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 42); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 3.14); - BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "qux"); - BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_integer(), 42); - BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_floating(), 3.14); - BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "qux"); - BOOST_CHECK_EQUAL(v1.as_table(std::nothrow).at("foo").as_integer(), 42); - BOOST_CHECK_EQUAL(v1.as_table(std::nothrow).at("bar").as_floating(), 3.14); - BOOST_CHECK_EQUAL(v1.as_table(std::nothrow).at("baz").as_string().str, "qux"); + BOOST_TEST(v1.cast().at("foo").cast() == 42); + BOOST_TEST(v1.cast().at("bar").cast() == 3.14); + BOOST_TEST(v1.cast().at("baz").cast().str == "qux"); + BOOST_TEST(v1.as_table().at("foo").as_integer() == 42); + BOOST_TEST(v1.as_table().at("bar").as_floating() == 3.14); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "qux"); + BOOST_TEST(v1.as_table(std::nothrow).at("foo").as_integer() == 42); + BOOST_TEST(v1.as_table(std::nothrow).at("bar").as_floating() == 3.14); + BOOST_TEST(v1.as_table(std::nothrow).at("baz").as_string().str == "qux"); v1 = {{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); - BOOST_CHECK(v1.is(toml::value_t::table)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_table()); + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); - BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); - BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); - BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_floating(), 2.71); - BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_integer(), 54); - BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "quux"); + BOOST_TEST(v1.cast().at("foo").cast() == 2.71); + BOOST_TEST(v1.cast().at("bar").cast() == 54); + BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); v1 = toml::table{{"foo", 2.71}, {"bar", 54}, {"baz", "quux"}}; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::table); - BOOST_CHECK(v1.is(toml::value_t::table)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_table()); + BOOST_TEST(v1.type() == toml::value_t::table); + BOOST_TEST(v1.is(toml::value_t::table)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_table()); - BOOST_CHECK_EQUAL(v1.cast().at("foo").cast(), 2.71); - BOOST_CHECK_EQUAL(v1.cast().at("bar").cast(), 54); - BOOST_CHECK_EQUAL(v1.cast().at("baz").cast().str, "quux"); - BOOST_CHECK_EQUAL(v1.as_table().at("foo").as_floating(), 2.71); - BOOST_CHECK_EQUAL(v1.as_table().at("bar").as_integer(), 54); - BOOST_CHECK_EQUAL(v1.as_table().at("baz").as_string().str, "quux"); + BOOST_TEST(v1.cast().at("foo").cast() == 2.71); + BOOST_TEST(v1.cast().at("bar").cast() == 54); + BOOST_TEST(v1.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v1.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v1.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v1.as_table().at("baz").as_string().str == "quux"); toml::value v3(v1); - BOOST_CHECK(v3 == v1); + BOOST_TEST(v3 == v1); - BOOST_CHECK_EQUAL(v3.type(), toml::value_t::table); - BOOST_CHECK(v3.is(toml::value_t::table)); - BOOST_CHECK(v3.is()); - BOOST_CHECK(v3.is_table()); + BOOST_TEST(v3.type() == toml::value_t::table); + BOOST_TEST(v3.is(toml::value_t::table)); + BOOST_TEST(v3.is()); + BOOST_TEST(v3.is_table()); - BOOST_CHECK_EQUAL(v3.cast().at("foo").cast(), 2.71); - BOOST_CHECK_EQUAL(v3.cast().at("bar").cast(), 54); - BOOST_CHECK_EQUAL(v3.cast().at("baz").cast().str, "quux"); - BOOST_CHECK_EQUAL(v3.as_table().at("foo").as_floating(), 2.71); - BOOST_CHECK_EQUAL(v3.as_table().at("bar").as_integer(), 54); - BOOST_CHECK_EQUAL(v3.as_table().at("baz").as_string().str, "quux"); + BOOST_TEST(v3.cast().at("foo").cast() == 2.71); + BOOST_TEST(v3.cast().at("bar").cast() == 54); + BOOST_TEST(v3.cast().at("baz").cast().str == "quux"); + BOOST_TEST(v3.as_table().at("foo").as_floating() == 2.71); + BOOST_TEST(v3.as_table().at("bar").as_integer() == 54); + BOOST_TEST(v3.as_table().at("baz").as_string().str == "quux"); v1 = true; - BOOST_CHECK_EQUAL(v1.type(), toml::value_t::boolean); - BOOST_CHECK(v1.is(toml::value_t::boolean)); - BOOST_CHECK(v1.is()); - BOOST_CHECK(v1.is_boolean()); - BOOST_CHECK_EQUAL(v1.cast(), true); - BOOST_CHECK_EQUAL(v1.as_boolean(), true); + BOOST_TEST(v1.type() == toml::value_t::boolean); + BOOST_TEST(v1.is(toml::value_t::boolean)); + BOOST_TEST(v1.is()); + BOOST_TEST(v1.is_boolean()); + BOOST_TEST(v1.cast() == true); + BOOST_TEST(v1.as_boolean() == true); } BOOST_AUTO_TEST_CASE(test_value_empty) { toml::value v1; - BOOST_CHECK(v1.is_uninitialized()); - BOOST_CHECK(v1.is(toml::value_t::empty)); + BOOST_TEST(v1.is_uninitialized()); + BOOST_TEST(v1.is(toml::value_t::empty)); BOOST_CHECK_THROW(v1.as_boolean(), toml::type_error); BOOST_CHECK_THROW(v1.as_integer(), toml::type_error); From b79797d2c774e8a9794ae6c17754483e2e6eedfb Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 15:58:22 +0900 Subject: [PATCH 132/162] refactor: replace BOOST_CHECK_EQUAL by BOOST_TEST --- tests/test_find.cpp | 8 ++-- tests/test_get_related_func.cpp | 82 ++++++++++++++++----------------- tests/test_parse_file.cpp | 24 ++++------ tests/test_parse_table.cpp | 14 +++--- tests/test_parse_unicode.cpp | 16 +++---- 5 files changed, 68 insertions(+), 76 deletions(-) diff --git a/tests/test_find.cpp b/tests/test_find.cpp index 28b076c..9fc95ca 100644 --- a/tests/test_find.cpp +++ b/tests/test_find.cpp @@ -102,20 +102,20 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_find_exact, value_type, test_value_types) } { value_type v{{"key", "foo"}}; - BOOST_CHECK_EQUAL(toml::string("foo", toml::string_t::basic), + BOOST_TEST(toml::string("foo", toml::string_t::basic) == toml::find(v, "key")); toml::find(v, "key").str += "bar"; - BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::basic), + BOOST_TEST(toml::string("foobar", toml::string_t::basic) == toml::find(v, "key")); } { value_type v{{"key", value_type("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::find(v, "key")); toml::find(v, "key").str += "bar"; - BOOST_CHECK_EQUAL(toml::string("foobar", toml::string_t::literal), + BOOST_TEST(toml::string("foobar", toml::string_t::literal) == toml::find(v, "key")); } { diff --git a/tests/test_get_related_func.cpp b/tests/test_get_related_func.cpp index 496b1b7..d3cf29b 100644 --- a/tests/test_get_related_func.cpp +++ b/tests/test_get_related_func.cpp @@ -20,8 +20,8 @@ BOOST_AUTO_TEST_CASE(test_get_or) { toml::value v1(42); toml::value v2(3.14); - BOOST_CHECK_EQUAL(42u, toml::get_or(v1, 0u)); - BOOST_CHECK_EQUAL(0u, toml::get_or(v2, 0u)); + BOOST_TEST(42u == toml::get_or(v1, 0u)); + BOOST_TEST(0u == toml::get_or(v2, 0u)); } // exact toml type @@ -30,14 +30,14 @@ BOOST_AUTO_TEST_CASE(test_get_or) toml::value v2(3.14); toml::integer opt(0); - BOOST_CHECK_EQUAL(42, toml::get_or(v1, opt)); - BOOST_CHECK_EQUAL(0, toml::get_or(v2, opt)); + BOOST_TEST(42 == toml::get_or(v1, opt)); + BOOST_TEST(0 == toml::get_or(v2, opt)); toml::value v3("foobar"); toml::string s("bazqux"); - BOOST_CHECK_EQUAL("foobar", toml::get_or(v3, s)); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v1, s)); + BOOST_TEST("foobar" == toml::get_or(v3, s)); + BOOST_TEST("bazqux" == toml::get_or(v1, s)); } @@ -49,20 +49,20 @@ BOOST_AUTO_TEST_CASE(test_get_or) std::string s1("bazqux"); const std::string s2("bazqux"); - BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, s1)); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, s1)); + 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_CHECK_EQUAL("foobar", v1r); - BOOST_CHECK_EQUAL("bazqux", s1r); + BOOST_TEST("foobar" == v1r); + BOOST_TEST("bazqux" == s1r); - BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, s2)); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, s2)); + BOOST_TEST("foobar" == toml::get_or(v1, s2)); + BOOST_TEST("bazqux" == toml::get_or(v2, s2)); - BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, std::move(s1))); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, std::move(s1))); + BOOST_TEST("foobar" == toml::get_or(v1, std::move(s1))); + BOOST_TEST("bazqux" == toml::get_or(v2, std::move(s1))); } // string literal @@ -70,12 +70,12 @@ BOOST_AUTO_TEST_CASE(test_get_or) toml::value v1("foobar"); toml::value v2(42); - BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, "bazqux")); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, "bazqux")); + BOOST_TEST("foobar" == toml::get_or(v1, "bazqux")); + BOOST_TEST("bazqux" == toml::get_or(v2, "bazqux")); const char* lit = "bazqux"; - BOOST_CHECK_EQUAL("foobar", toml::get_or(v1, lit)); - BOOST_CHECK_EQUAL("bazqux", toml::get_or(v2, lit)); + BOOST_TEST("foobar" == toml::get_or(v1, lit)); + BOOST_TEST("bazqux" == toml::get_or(v2, lit)); } } @@ -84,8 +84,8 @@ BOOST_AUTO_TEST_CASE(test_find_or) // requires conversion int -> uint { toml::value v = toml::table{{"num", 42}}; - BOOST_CHECK_EQUAL(42u, toml::find_or(v, "num", 0u)); - BOOST_CHECK_EQUAL(0u, toml::find_or(v, "foo", 0u)); + BOOST_TEST(42u == toml::find_or(v, "num", 0u)); + BOOST_TEST(0u == toml::find_or(v, "foo", 0u)); } // exact toml type { @@ -93,15 +93,15 @@ BOOST_AUTO_TEST_CASE(test_find_or) toml::value v2 = toml::table{{"key", 3.14}}; toml::value v3 = toml::table{{"not", "key"}}; - BOOST_CHECK_EQUAL(42, toml::find_or(v1, "key", toml::integer(0))); - BOOST_CHECK_EQUAL( 0, toml::find_or(v2, "key", toml::integer(0))); - BOOST_CHECK_EQUAL( 0, toml::find_or(v3, "key", toml::integer(0))); + BOOST_TEST(42 == toml::find_or(v1, "key", toml::integer(0))); + BOOST_TEST( 0 == toml::find_or(v2, "key", toml::integer(0))); + BOOST_TEST( 0 == toml::find_or(v3, "key", toml::integer(0))); toml::value v4 = toml::table{{"str", "foobar"}}; toml::string s("bazqux"); - BOOST_CHECK_EQUAL("foobar", toml::find_or(v4, "str", s)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v1, "str", s)); + BOOST_TEST("foobar" == toml::find_or(v4, "str", s)); + BOOST_TEST("bazqux" == toml::find_or(v1, "str", s)); } // std::string { @@ -111,33 +111,33 @@ BOOST_AUTO_TEST_CASE(test_find_or) std::string s1("bazqux"); const std::string s2("bazqux"); - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s1)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s1)); + 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_CHECK_EQUAL("foobar", v1r); - BOOST_CHECK_EQUAL("bazqux", s1r); + BOOST_TEST("foobar" == v1r); + BOOST_TEST("bazqux" == s1r); - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", s2)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", s2)); + BOOST_TEST("foobar" == toml::find_or(v1, "key", s2)); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", s2)); - BOOST_CHECK_EQUAL("foobar", toml::find_or(std::move(v1), "key", std::move(s1))); + BOOST_TEST("foobar" == toml::find_or(std::move(v1), "key", std::move(s1))); s1 = "bazqux"; // restoring moved value - BOOST_CHECK_EQUAL("bazqux", toml::find_or(std::move(v2), "key", std::move(s1))); + 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_CHECK_EQUAL("foobar", toml::find_or(v1, "key", "bazqux")); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", "bazqux")); + BOOST_TEST("foobar" == toml::find_or(v1, "key", "bazqux")); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", "bazqux")); const char* lit = "bazqux"; - BOOST_CHECK_EQUAL("foobar", toml::find_or(v1, "key", lit)); - BOOST_CHECK_EQUAL("bazqux", toml::find_or(v2, "key", lit)); + BOOST_TEST("foobar" == toml::find_or(v1, "key", lit)); + BOOST_TEST("bazqux" == toml::find_or(v2, "key", lit)); } } @@ -148,12 +148,12 @@ BOOST_AUTO_TEST_CASE(test_expect) toml::value v2(3.14); const auto v1_or_0 = toml::expect(v1).unwrap_or(0); const auto v2_or_0 = toml::expect(v2).unwrap_or(0); - BOOST_CHECK_EQUAL(42, v1_or_0); - BOOST_CHECK_EQUAL( 0, v2_or_0); + BOOST_TEST(42 == v1_or_0); + BOOST_TEST( 0 == v2_or_0); const auto v1_or_none = toml::expect(v1).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); const auto v2_or_none = toml::expect(v2).map([](int i){return std::to_string(i);}).unwrap_or(std::string("none")); - BOOST_CHECK_EQUAL("42", v1_or_none); - BOOST_CHECK_EQUAL("none", v2_or_none); + BOOST_TEST("42" == v1_or_none); + BOOST_TEST("none" == v2_or_none); } } diff --git a/tests/test_parse_file.cpp b/tests/test_parse_file.cpp index 0e8c781..7a3dc8f 100644 --- a/tests/test_parse_file.cpp +++ b/tests/test_parse_file.cpp @@ -31,8 +31,7 @@ BOOST_AUTO_TEST_CASE(test_example) { BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - const bool result = toml::find>(database, "ports") == expected_ports; - BOOST_TEST(result); + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); BOOST_TEST(toml::find(database, "connection_max") == 5000); BOOST_TEST(toml::find(database, "enabled") == true); } @@ -54,16 +53,13 @@ BOOST_AUTO_TEST_CASE(test_example) toml::array clients_data = toml::find(clients, "data"); std::vector expected_name{"gamma", "delta"}; - const bool result1 = toml::get>(clients_data.at(0)) == expected_name; - BOOST_TEST(reuslt1); + BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); std::vector expected_number{1, 2}; - const bool result2 = toml::get>(clients_data.at(1)) == expected_number; - BOOST_TEST(reuslt2); + BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); std::vector expected_hosts{"alpha", "omega"}; - const bool result3 = toml::find>(clients, "hosts") == expected_hosts; - BOOST_TEST(reuslt3); + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); } std::vector products = @@ -99,8 +95,7 @@ BOOST_AUTO_TEST_CASE(test_example_stream) { BOOST_TEST(toml::find(database, "server") == "192.168.1.1"); const std::vector expected_ports{8001, 8001, 8002}; - const bool result = (toml::find>(database, "ports") == expected_ports); - BOOST_TEST(result); + BOOST_CHECK(toml::find>(database, "ports") == expected_ports); BOOST_TEST(toml::find(database, "connection_max") == 5000); BOOST_TEST(toml::find(database, "enabled") == true); } @@ -121,16 +116,13 @@ BOOST_AUTO_TEST_CASE(test_example_stream) { toml::array clients_data = toml::find(clients, "data"); std::vector expected_name{"gamma", "delta"}; - const bool result1 = toml::get>(clients_data.at(0)) == expected_name; - BOOST_TEST(reuslt1); + BOOST_CHECK(toml::get>(clients_data.at(0)) == expected_name); std::vector expected_number{1, 2}; - const bool result2 = toml::get>(clients_data.at(1)) == expected_number; - BOOST_TEST(reuslt2); + BOOST_CHECK(toml::get>(clients_data.at(1)) == expected_number); std::vector expected_hosts{"alpha", "omega"}; - const bool result3 = toml::find>(clients, "hosts") == expected_hosts; - BOOST_TEST(reuslt3); + BOOST_CHECK(toml::find>(clients, "hosts") == expected_hosts); } std::vector products = diff --git a/tests/test_parse_table.cpp b/tests/test_parse_table.cpp index 6d95ef0..e30e257 100644 --- a/tests/test_parse_table.cpp +++ b/tests/test_parse_table.cpp @@ -22,12 +22,12 @@ BOOST_AUTO_TEST_CASE(test_normal_table) location loc("test", table); const auto result = toml::detail::parse_ml_table(loc); - BOOST_CHECK(result.is_ok()); + BOOST_TEST(result.is_ok()); const auto data = result.unwrap(); - BOOST_CHECK_EQUAL(toml::get(data.at("key1")), "value"); - BOOST_CHECK_EQUAL(toml::get(data.at("key2")), 42); - BOOST_CHECK_EQUAL(toml::get(data.at("key3")), 3.14); + BOOST_TEST(toml::get(data.at("key1")) == "value"); + BOOST_TEST(toml::get(data.at("key2")) == 42); + BOOST_TEST(toml::get(data.at("key3")) == 3.14); } BOOST_AUTO_TEST_CASE(test_nested_table) @@ -39,12 +39,12 @@ BOOST_AUTO_TEST_CASE(test_nested_table) location loc("test", table); const auto result = toml::detail::parse_ml_table(loc); - BOOST_CHECK(result.is_ok()); + BOOST_TEST(result.is_ok()); const auto data = result.unwrap(); const auto a = toml::get(data.at("a")); const auto c = toml::get(a.at("c")); - BOOST_CHECK_EQUAL(toml::get(a.at("b")), "value"); - BOOST_CHECK_EQUAL(toml::get(c.at("d")), 42); + BOOST_TEST(toml::get(a.at("b")) == "value"); + BOOST_TEST(toml::get(c.at("d")) == 42); } diff --git a/tests/test_parse_unicode.cpp b/tests/test_parse_unicode.cpp index 30d909a..dbfe601 100644 --- a/tests/test_parse_unicode.cpp +++ b/tests/test_parse_unicode.cpp @@ -15,7 +15,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) const auto data = toml::parse("toml/tests/hard_example_unicode.toml"); const auto the = toml::find(data, "the"); - BOOST_CHECK_EQUAL(toml::get(the.at("test_string")), + BOOST_TEST(toml::get(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")); const auto hard = toml::get(the.at("hard")); @@ -28,13 +28,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) }; BOOST_CHECK(toml::get>(hard.at("test_array2")) == expected_the_hard_test_array2); - BOOST_CHECK_EQUAL(toml::get(hard.at("another_test_string")), + BOOST_TEST(toml::get(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")); - BOOST_CHECK_EQUAL(toml::get(hard.at("harder_test_string")), + BOOST_TEST(toml::get(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")); // const auto bit = toml::get(hard.at(std::string("\xCE\xB2\xC3\xAF\xC6\xAD\x23"))); - BOOST_CHECK_EQUAL(toml::get(bit.at(std::string("\xCF\x89\xCE\xBB\xC3\xA1\xC6\xAD\x3F"))), + BOOST_TEST(toml::get(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")); const std::vector expected_multi_line_array{"]"}; BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) const auto data = toml::parse("toml/tests/hard_example_unicode.toml"); const auto the = toml::find(data, "the"); - BOOST_CHECK_EQUAL(toml::get(the.at("test_string")), + BOOST_TEST(toml::get(the.at("test_string")) == std::string(u8"Ýôú'ℓℓ λáƭè ₥è áƒƭèř ƭλïƨ - #")); const auto hard = toml::get(the.at("hard")); @@ -58,13 +58,13 @@ BOOST_AUTO_TEST_CASE(test_hard_example_unicode) std::string(u8"Éжƥèřï₥èñƭ #9 ωáƨ á ƨúççèƨƨ")}; BOOST_CHECK(toml::get>(hard.at("test_array2")) == expected_the_hard_test_array2); - BOOST_CHECK_EQUAL(toml::get(hard.at("another_test_string")), + BOOST_TEST(toml::get(hard.at("another_test_string")) == std::string(u8"§á₥è ƭλïñϱ, βúƭ ωïƭλ á ƨƭřïñϱ #")); - BOOST_CHECK_EQUAL(toml::get(hard.at("harder_test_string")), + BOOST_TEST(toml::get(hard.at("harder_test_string")) == std::string(u8" Âñδ ωλèñ \"'ƨ ářè ïñ ƭλè ƨƭřïñϱ, áℓôñϱ ωïƭλ # \"")); const auto bit = toml::get(hard.at(std::string(u8"βïƭ#"))); - BOOST_CHECK_EQUAL(toml::get(bit.at(std::string(u8"ωλáƭ?"))), + BOOST_TEST(toml::get(bit.at(std::string(u8"ωλáƭ?"))) == std::string(u8"Ýôú δôñ'ƭ ƭλïñƙ ƨô₥è úƨèř ωôñ'ƭ δô ƭλáƭ?")); const std::vector expected_multi_line_array{"]"}; BOOST_CHECK(toml::get>(bit.at("multi_line_array")) == From a343ffd2a183609d0a0ee4ffc4bc51bd0a23ebc3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 17:02:30 +0900 Subject: [PATCH 133/162] doc: update README --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cdd997f..7dda2d4 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,8 @@ int main() } ``` -The convenient way is to add this repository as a git-submodule. +The convenient way is to add this repository as a git-submodule or to install +it in your system by CMake. ## Decoding a toml file @@ -485,11 +486,6 @@ toml::value v = /* ... */; if(v.is(toml::value_t::boolean)) // ... ``` -**NOTE**: BREAKING CHANGES from v2.y.z: `(is|as)_float` has been removed. -Use `(is|as)_floating` instead. -See [Breaking Changes from v2](#breaking-changes-from-v2) for the complete list -of breaking changes. - ## More about conversion Since `toml::find` internally uses `toml::get`, all the following examples work @@ -1066,8 +1062,8 @@ you can add conversion between `toml::value` and classes defined in another libr Note that you cannot implement both of the functions because the overload resolution of `toml::get` will be ambiguous. -If you want to convert arbitrary specialization of `toml::basic_value`, -templatize the conversion function as follows. +If you want to convert any versions of `toml::basic_value`, +you need to templatize the conversion function as follows. ```cpp struct foo From 0ca8eeeb09f7ce8c489b275b8dd3b083e46d6955 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 21 Jun 2019 17:11:21 +0900 Subject: [PATCH 134/162] test: add missing include files --- tests/test_serialize_file.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 5c963b8..7fe61f6 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -6,6 +6,8 @@ #include #endif #include +#include +#include #include #include From 1e8af710a042ba53ac5d36599488b4f19a6be811 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 16:39:01 +0900 Subject: [PATCH 135/162] test: add test for get_or --- tests/CMakeLists.txt | 1 + tests/test_get_or.cpp | 360 ++++++++++++++++++++++++++++++++ tests/test_get_related_func.cpp | 67 ------ 3 files changed, 361 insertions(+), 67 deletions(-) create mode 100644 tests/test_get_or.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 903272d..4ee2b70 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -23,6 +23,7 @@ set(TEST_NAMES test_literals test_comments test_get + test_get_or test_find test_get_related_func test_parse_file diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp new file mode 100644 index 0000000..d8914ad --- /dev/null +++ b/tests/test_get_or.cpp @@ -0,0 +1,360 @@ +#define BOOST_TEST_MODULE "test_get" +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +#include +#else +#define BOOST_TEST_NO_LIB +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#if __cplusplus >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +namespace test +{ +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::vector& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::deque& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::list& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::unordered_map& 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(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(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(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(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)); + } +} diff --git a/tests/test_get_related_func.cpp b/tests/test_get_related_func.cpp index d3cf29b..df644b3 100644 --- a/tests/test_get_related_func.cpp +++ b/tests/test_get_related_func.cpp @@ -12,73 +12,6 @@ #include #include - - -BOOST_AUTO_TEST_CASE(test_get_or) -{ - // requires conversion int -> uint - { - 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)); - } - - // exact toml type - { - toml::value v1(42); - toml::value v2(3.14); - - toml::integer opt(0); - BOOST_TEST(42 == toml::get_or(v1, opt)); - BOOST_TEST(0 == toml::get_or(v2, opt)); - - toml::value v3("foobar"); - toml::string s("bazqux"); - - BOOST_TEST("foobar" == toml::get_or(v3, s)); - BOOST_TEST("bazqux" == toml::get_or(v1, s)); - - } - - // std::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))); - } - - // string literal - { - 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)); - } -} - BOOST_AUTO_TEST_CASE(test_find_or) { // requires conversion int -> uint From 3fcb6bb20d0a88eeae4eed9af720fd01f3ab1229 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 16:58:21 +0900 Subject: [PATCH 136/162] test: fix test module name --- tests/test_get_or.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_get_or.cpp b/tests/test_get_or.cpp index d8914ad..0c12a07 100644 --- a/tests/test_get_or.cpp +++ b/tests/test_get_or.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE "test_get" +#define BOOST_TEST_MODULE "test_get_or" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST #include #else From 4d2b24b6470014070c6cfc4e4980684b7f7aaa6c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 16:58:45 +0900 Subject: [PATCH 137/162] test: add test_find_or --- tests/CMakeLists.txt | 1 + tests/test_find_or.cpp | 360 ++++++++++++++++++++++++++++++++ tests/test_get_related_func.cpp | 64 +----- 3 files changed, 362 insertions(+), 63 deletions(-) create mode 100644 tests/test_find_or.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4ee2b70..e8358ab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,6 +25,7 @@ set(TEST_NAMES test_get test_get_or test_find + test_find_or test_get_related_func test_parse_file test_serialize_file diff --git a/tests/test_find_or.cpp b/tests/test_find_or.cpp new file mode 100644 index 0000000..09e1e2e --- /dev/null +++ b/tests/test_find_or.cpp @@ -0,0 +1,360 @@ +#define BOOST_TEST_MODULE "test_find_or" +#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST +#include +#else +#define BOOST_TEST_NO_LIB +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#if __cplusplus >= 201703L +#include +#endif + +using test_value_types = std::tuple< + toml::value, + toml::basic_value, + toml::basic_value, + toml::basic_value +>; + +namespace test +{ +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::vector& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::deque& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const std::list& v) +{ + os << "[ "; + for(const auto& i : v) {os << i << ' ';} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::map& v) +{ + os << "[ "; + for(const auto& i : v) {os << '{' << i.first << ", " << i.second << "} ";} + os << ']'; + return os; +} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, + const std::unordered_map& 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(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(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(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(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)); + } +} diff --git a/tests/test_get_related_func.cpp b/tests/test_get_related_func.cpp index df644b3..2971f0c 100644 --- a/tests/test_get_related_func.cpp +++ b/tests/test_get_related_func.cpp @@ -1,4 +1,4 @@ -#define BOOST_TEST_MODULE "test_get_or" +#define BOOST_TEST_MODULE "test_expect" #ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST #include #else @@ -12,68 +12,6 @@ #include #include -BOOST_AUTO_TEST_CASE(test_find_or) -{ - // requires conversion int -> uint - { - 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)); - } - // exact toml type - { - toml::value v1 = toml::table{{"key", 42 }}; - toml::value v2 = toml::table{{"key", 3.14}}; - toml::value v3 = toml::table{{"not", "key"}}; - - BOOST_TEST(42 == toml::find_or(v1, "key", toml::integer(0))); - BOOST_TEST( 0 == toml::find_or(v2, "key", toml::integer(0))); - BOOST_TEST( 0 == toml::find_or(v3, "key", toml::integer(0))); - - toml::value v4 = toml::table{{"str", "foobar"}}; - toml::string s("bazqux"); - - BOOST_TEST("foobar" == toml::find_or(v4, "str", s)); - BOOST_TEST("bazqux" == toml::find_or(v1, "str", s)); - } - // std::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)); - } -} - BOOST_AUTO_TEST_CASE(test_expect) { { From 3a5f8a4b88731c87e79776ed4bda4a6eae04fb77 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 16:59:21 +0900 Subject: [PATCH 138/162] test: rename test source file --- tests/CMakeLists.txt | 2 +- tests/{test_get_related_func.cpp => test_expect.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{test_get_related_func.cpp => test_expect.cpp} (100%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e8358ab..01d038c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -26,7 +26,7 @@ set(TEST_NAMES test_get_or test_find test_find_or - test_get_related_func + test_expect test_parse_file test_serialize_file test_parse_unicode diff --git a/tests/test_get_related_func.cpp b/tests/test_expect.cpp similarity index 100% rename from tests/test_get_related_func.cpp rename to tests/test_expect.cpp From 74ef4947973e5ac5677d57dcc0f213435c3c94c6 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 17:35:40 +0900 Subject: [PATCH 139/162] feat: remove unused trait types --- toml/types.hpp | 52 -------------------------------------------------- 1 file changed, 52 deletions(-) diff --git a/toml/types.hpp b/toml/types.hpp index 6e7fbaa..b289d2d 100644 --- a/toml/types.hpp +++ b/toml/types.hpp @@ -144,58 +144,6 @@ template struct is_exact_toml_type template struct is_exact_toml_type : is_exact_toml_type{}; template struct is_exact_toml_type: is_exact_toml_type{}; -// meta-function that check type T is convertible to toml::* types -template -struct is_convertible_to_toml_value : disjunction< - std::is_same, // T is bool or - std::is_integral, // T is an integer or - std::is_floating_point, // T is a floating point or - std::is_same, // T is std::string or - std::is_same, // T is toml::string or - is_string_literal, // T is "string literal" or - std::is_same, // T is local_date or - std::is_same, // T is local_time or - std::is_same, // T is local_datetime or - std::is_same, // T is offset_datetime or - std::is_same, // T is time_point or - is_chrono_duration, // T is a duration or - std::is_same, // T is an array type or - std::is_same // T is an array type or - >{}; - -// meta-function that returns value_t that represent the convertible type -template -struct convertible_toml_type_of : std::conditional< - /* if */ is_exact_toml_type::value, - /* then */ value_t_constant::value>, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ std::is_integral::value, - /* then */ value_t_constant, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ std::is_floating_point::value, - /* then */ value_t_constant, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ std::is_same::value, - /* then */ value_t_constant, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ is_string_literal::value, - /* then */ value_t_constant, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ is_chrono_duration::value, - /* then */ value_t_constant, - /* else */ typename std::conditional< - // ---------------------------------------------------------------------- - /* if */ std::is_same::value, - /* then */ value_t_constant, - /* else */ value_t_constant - // ---------------------------------------------------------------------- - >::type>::type>::type>::type>::type>::type>::type {}; - } // detail } // toml #endif// TOML11_TYPES_H From 6a251f582ec229bf0c84ba6a0c1805cb78122bad Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 22 Jun 2019 17:52:01 +0900 Subject: [PATCH 140/162] refactor: remove needless code snippet --- toml/literal.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/toml/literal.hpp b/toml/literal.hpp index bc4733b..783d309 100644 --- a/toml/literal.hpp +++ b/toml/literal.hpp @@ -72,11 +72,6 @@ inline ::toml::value operator"" _toml(const char* str, std::size_t len) if(auto data = ::toml::detail::parse_toml_file<::toml::value>(loc)) { - // TODO later I need to move this logic to parse_toml_file -// loc.reset(loc.begin()); // rollback to the top of the literal -// // skip needless characters for error message -// skip_line::invoke(loc); // skip the first several needless lines -// skip_ws::invoke(loc); // skip the first several needless whitespaces return data.unwrap(); } else // none of them. From b4bbd0a005e58890288e7cf79e1c4a8a8d93f895 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 26 Jun 2019 21:31:35 +0900 Subject: [PATCH 141/162] chore: update version string in CMakeLists --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f25812d..16bcb2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,11 +3,11 @@ enable_testing() project(toml11) -set(toml11_VERSION_MAYOR 2) -set(toml11_VERSION_MINOR 4) +set(toml11_VERSION_MAYOR 3) +set(toml11_VERSION_MINOR 0) set(toml11_VERSION_PATCH 0) set(toml11_VERSION - "${toml11_VERSION_MAYOR}.${toml11_VERSION_MINOR}.${toml11_VERSION_PATCH}" + "${toml11_VERSION_MAYOR}.${toml11_VERSION_MINOR}.${toml11_VERSION_PATCH}-beta" ) option(toml11_BUILD_TEST "Build toml tests" ON) From 76e44a0c48526d20efccba32b919b391404887d2 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 26 Jun 2019 21:34:36 +0900 Subject: [PATCH 142/162] refactor: remove needless inline specifier --- toml/parser.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/parser.hpp b/toml/parser.hpp index a7cf57e..d70282a 100644 --- a/toml/parser.hpp +++ b/toml/parser.hpp @@ -1973,7 +1973,7 @@ parse(std::istream& is, const std::string& fname = "unknown file") template class Table = std::unordered_map, template class Array = std::vector> -inline basic_value parse(const std::string& fname) +basic_value parse(const std::string& fname) { std::ifstream ifs(fname.c_str(), std::ios_base::binary); if(!ifs.good()) From 6b5fd349aad36ae62d5795ade50c6700465fb5c5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Wed, 26 Jun 2019 21:35:01 +0900 Subject: [PATCH 143/162] fix: initialize source_location correctly --- toml/value.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toml/value.hpp b/toml/value.hpp index 56bb948..3d24c83 100644 --- a/toml/value.hpp +++ b/toml/value.hpp @@ -1569,7 +1569,7 @@ class basic_value source_location location() const { - return source_location(this->region_info_); + return source_location(this->region_info_.get()); } comment_type const& comments() const noexcept {return this->comments_;} From 28b3f7d6fbb026a917f5f89f9dcb450a4c3f816f Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 14:57:45 +0900 Subject: [PATCH 144/162] feat: add ostream operator to comment containers --- toml/comments.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/toml/comments.hpp b/toml/comments.hpp index 98f36c8..3ce88a1 100644 --- a/toml/comments.hpp +++ b/toml/comments.hpp @@ -187,6 +187,17 @@ inline void swap(preserve_comments& lhs, preserve_comments& rhs) return; } +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const preserve_comments& com) +{ + for(const auto& c : com) + { + os << '#' << c << '\n'; + } + return os; +} + namespace detail { @@ -381,5 +392,12 @@ inline bool operator>=(const discard_comments&, const discard_comments&) noexcep inline void swap(const discard_comments&, const discard_comments&) noexcept {return;} +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const discard_comments&) +{ + return os; +} + } // toml11 #endif// TOML11_COMMENTS_HPP From 134475e292505bd5d7dcac649e4c87834e2df77a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 14:58:16 +0900 Subject: [PATCH 145/162] test: check ostream op for comment containers --- tests/test_comments.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 1852dee..5a3389c 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -460,3 +460,19 @@ BOOST_AUTO_TEST_CASE(test_overwrite_comments) BOOST_TEST(u.as_integer() == 42); } } + +BOOST_AUTO_TEST_CASE(test_output_comments) +{ + using value_type = toml::basic_value; + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + oss << v.comments(); + + std::ostringstream ref; + ref << "#comment1\n"; + ref << "#comment2\n"; + + BOOST_TEST(oss.str() == ref.str()); + } +} From 284f122433ce77839ec2ac92b7861c422d76c860 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 14:58:47 +0900 Subject: [PATCH 146/162] refactor: replace for-loop by comment output --- toml/serializer.hpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 4711236..01b894f 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -633,11 +633,8 @@ format(const basic_value& v, std::size_t w = 80u, std::ostringstream oss; if(!v.comments().empty()) { - for(const auto& c : v.comments()) - { - oss << '#' << c << '\n'; - } - oss << '\n'; + oss << v.comments(); + oss << '\n'; // to split the file comment from the first element } oss << visit(serializer(w, fprec, false), v); return oss.str(); @@ -657,11 +654,8 @@ operator<<(std::basic_ostream& os, const basic_value& v) if(!v.comments().empty()) { - for(const auto& c : v.comments()) - { - os << '#' << c << '\n'; - } - os << '\n'; + os << v.comments(); + os << '\n'; // to split the file comment from the first element } // the root object can't be an inline table. so pass `false`. os << visit(serializer(w, fprec, false), v); From 79e7511871ffe473d283132faa3c4d7f925795da Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 17:47:19 +0900 Subject: [PATCH 147/162] feat: add format_key to help serialization --- toml/serializer.hpp | 50 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 01b894f..eb42515 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -10,6 +10,45 @@ namespace toml { +// This function serialize a key. It checks a string is a bare key and +// escapes special characters if the string is not compatible to a bare key. +// ```cpp +// std::string k("non.bare.key"); // the key itself includes `.`s. +// std::string formatted = toml::format_key(k); +// assert(formatted == "\"non.bare.key\""); +// ``` +// +// This function is exposed to make it easy to write a user-defined serializer. +// Since toml restricts characters available in a bare key, generally a string +// should be escaped. But checking whether a string needs to be surrounded by +// a `"` and escaping some special character is boring. +inline std::string format_key(const toml::key& key) +{ + detail::location 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("\""); + for(const char c : key) + { + switch(c) + { + case '\\': {token += "\\\\"; break;} + case '\"': {token += "\\\""; break;} + case '\b': {token += "\\b"; break;} + case '\t': {token += "\\t"; break;} + case '\f': {token += "\\f"; break;} + case '\n': {token += "\\n"; break;} + case '\r': {token += "\\r"; break;} + default : {token += c; break;} + } + } + token += "\""; + return token; +} + template class Table, template class Array> @@ -390,16 +429,7 @@ struct serializer std::string serialize_key(const toml::key& key) const { - detail::location 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; + return ::toml::format_key(key); } std::string serialize_dotted_key(const std::vector& keys) const From 37e96ed8dcaab1d9e62d69e806e0b33da50e4732 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 17:47:42 +0900 Subject: [PATCH 148/162] test: add test for format_key() --- tests/test_serialize_file.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 7fe61f6..8c513a8 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -194,3 +194,23 @@ BOOST_AUTO_TEST_CASE(test_hard_example_with_comment) } BOOST_TEST(data == serialized); } + +BOOST_AUTO_TEST_CASE(test_format_key) +{ + { + const toml::key key("normal_bare-key"); + BOOST_TEST("normal_bare-key" == toml::format_key(key)); + } + { + const toml::key key("key.include.dots"); + BOOST_TEST("\"key.include.dots\"" == toml::format_key(key)); + } + { + const toml::key key("key-include-unicode-\xE3\x81\x82"); + BOOST_TEST("\"key-include-unicode-\xE3\x81\x82\"" == toml::format_key(key)); + } + { + const toml::key key("special-chars-\\-\"-\b-\f-\r-\n-\t"); + BOOST_TEST("\"special-chars-\\\\-\\\"-\\b-\\f-\\r-\\n-\\t\"" == toml::format_key(key)); + } +} From 3624e4b69004b7877f3a6a5c3b49506e0bc6e70e Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 17:53:19 +0900 Subject: [PATCH 149/162] fix: put comment just after non-table values When non-table value is passed to the `operator<<`, it assumes that the original C++ code looks like the following. ```cpp std::cout << "key = " << v << std::endl; ``` In this case, the comment associated to `v` should be put just after `v`, not before. ```toml key = # comment <= bad "value" key = "value" # comment <= good ``` So, if `v` is not a table it would put comments just after the value. --- toml/serializer.hpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index eb42515..95df73e 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -682,13 +682,36 @@ operator<<(std::basic_ostream& os, const basic_value& v) const int fprec = static_cast(os.precision()); os.width(0); - if(!v.comments().empty()) + if(v.is_table() && !v.comments().empty()) { os << v.comments(); os << '\n'; // to split the file comment from the first element } // the root object can't be an inline table. so pass `false`. os << visit(serializer(w, fprec, false), v); + + // if v is a non-table value, and has only one comment, then + // put a comment just after a value. in the following way. + // + // ```toml + // key = "value" # comment. + // ``` + // + // Since the top-level toml object is a table, one who want to put a + // non-table toml value must use this in a following way. + // + // ```cpp + // toml::value v; + // std::cout << "user-defined-key = " << v << std::endl; + // ``` + // + // In this case, it is impossible to put comments before key-value pair. + // The only way to preserve comments is to put all of them after a value. + if(!v.is_table() && !v.comments().empty()) + { + os << " #"; + for(const auto& c : v.comments()) {os << c;} + } return os; } From 6182f3ee9d429128a0717f2f7e6941241e600d74 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 17:56:41 +0900 Subject: [PATCH 150/162] test: add test for operator<<(os, non-table-value) --- tests/test_comments.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 5a3389c..3164bf8 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -475,4 +475,15 @@ BOOST_AUTO_TEST_CASE(test_output_comments) BOOST_TEST(oss.str() == ref.str()); } + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); + } } From 0502924d250f004a976c532d5bd8ad1ff132ea32 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 19:08:48 +0900 Subject: [PATCH 151/162] feat: add nocomment and showcomment --- toml/serializer.hpp | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 95df73e..e6d8c81 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -672,6 +672,34 @@ format(const basic_value& v, std::size_t w = 80u, return visit(serializer(w, fprec, force_inline), v); } +namespace detail +{ +template +int comment_index(std::basic_ostream&) +{ + static const int index = std::ios_base::xalloc(); + return index; +} +} // detail + +template +std::basic_ostream& +nocomment(std::basic_ostream& os) +{ + // by default, it is zero. and by defalut, it shows comments. + os.iword(detail::comment_index(os)) = 1; + return os; +} + +template +std::basic_ostream& +showcomment(std::basic_ostream& os) +{ + // by default, it is zero. and by defalut, it shows comments. + os.iword(detail::comment_index(os)) = 0; + return os; +} + template class M, template class V> std::basic_ostream& @@ -682,7 +710,11 @@ operator<<(std::basic_ostream& os, const basic_value& v) const int fprec = static_cast(os.precision()); os.width(0); - if(v.is_table() && !v.comments().empty()) + // by defualt, iword is initialized byl 0. And by default, toml11 outputs + // comments. So `0` means showcomment. 1 means nocommnet. + const bool show_comment = (0 == os.iword(detail::comment_index(os))); + + if(show_comment && v.is_table() && !v.comments().empty()) { os << v.comments(); os << '\n'; // to split the file comment from the first element @@ -707,7 +739,7 @@ operator<<(std::basic_ostream& os, const basic_value& v) // // In this case, it is impossible to put comments before key-value pair. // The only way to preserve comments is to put all of them after a value. - if(!v.is_table() && !v.comments().empty()) + if(show_comment && !v.is_table() && !v.comments().empty()) { os << " #"; for(const auto& c : v.comments()) {os << c;} From 937a3b4a2e8a83360144b4f6e2ce75ed038c0f52 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Fri, 28 Jun 2019 19:09:05 +0900 Subject: [PATCH 152/162] test: add test for nocomment/showcomment --- tests/test_comments.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_comments.cpp b/tests/test_comments.cpp index 3164bf8..797c39d 100644 --- a/tests/test_comments.cpp +++ b/tests/test_comments.cpp @@ -486,4 +486,29 @@ BOOST_AUTO_TEST_CASE(test_output_comments) BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); } + + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << toml::nocomment << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42"); + } + + { + const value_type v(42, {"comment1", "comment2"}); + std::ostringstream oss; + + // If v is not a table, toml11 assumes that user is writing something + // like the following. + + oss << toml::nocomment << toml::showcomment << "answer = " << v; + + BOOST_TEST(oss.str() == "answer = 42 #comment1comment2"); + } + } From d5299fef046bf4414a79d7a7966e1679b382f897 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 14:59:18 +0900 Subject: [PATCH 153/162] feat: add no_comment option to serializer --- toml/serializer.hpp | 56 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index e6d8c81..0761b17 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -71,9 +71,10 @@ struct serializer serializer(const std::size_t w = 80u, const int float_prec = std::numeric_limits::max_digits10, const bool can_be_inlined = false, + const bool no_comment = false, std::vector ks = {}) - : can_be_inlined_(can_be_inlined), float_prec_(float_prec), width_(w), - keys_(std::move(ks)) + : can_be_inlined_(can_be_inlined), no_comment_(no_comment), + float_prec_(float_prec), width_(w), keys_(std::move(ks)) {} ~serializer() = default; @@ -256,11 +257,14 @@ struct serializer failed = true; break; } - for(const auto& c : item.comments()) + if(!no_comment_) { - token += '#'; - token += c; - token += '\n'; + for(const auto& c : item.comments()) + { + token += '#'; + token += c; + token += '\n'; + } } const auto t = this->make_inline_table(item.as_table()); @@ -285,11 +289,14 @@ struct serializer std::string token; for(const auto& item : v) { - for(const auto& c : item.comments()) + if(!no_comment_) { - token += '#'; - token += c; - token += '\n'; + for(const auto& c : item.comments()) + { + token += '#'; + token += c; + token += '\n'; + } } token += "[["; token += this->serialize_dotted_key(keys_); @@ -326,7 +333,7 @@ struct serializer token += "[\n"; for(const auto& item : v) { - if(!item.comments().empty()) + if(!item.comments().empty() && !no_comment_) { // if comment exists, the element must be the only element in the line. // e.g. the following is not allowed. @@ -502,6 +509,9 @@ struct serializer // 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 { + // if no_comment is set, comments would not be written. + if(this->no_comment_) {return false;} + for(const auto& v : a) { if(!v.comments().empty()) {return true;} @@ -510,6 +520,9 @@ struct serializer } bool has_comment_inside(const table_type& t) const noexcept { + // if no_comment is set, comments would not be written. + if(this->no_comment_) {return false;} + for(const auto& kv : t) { if(!kv.second.comments().empty()) {return true;} @@ -566,7 +579,7 @@ struct serializer continue; } - if(!kv.second.comments().empty()) + if(!kv.second.comments().empty() && !no_comment_) { for(const auto& c : kv.second.comments()) { @@ -605,8 +618,8 @@ struct serializer std::vector ks(this->keys_); ks.push_back(kv.first); - auto tmp = visit(serializer( - this->width_, this->float_prec_, !multiline_table_printed, ks), + auto tmp = visit(serializer(this->width_, this->float_prec_, + !multiline_table_printed, this->no_comment_, ks), kv.second); if((!multiline_table_printed) && @@ -620,7 +633,7 @@ struct serializer tmp += '\n'; } - if(!kv.second.comments().empty()) + if(!kv.second.comments().empty() && !no_comment_) { for(const auto& c : kv.second.comments()) { @@ -644,6 +657,7 @@ struct serializer private: bool can_be_inlined_; + bool no_comment_; int float_prec_; std::size_t width_; std::vector keys_; @@ -654,7 +668,7 @@ template& v, std::size_t w = 80u, int fprec = std::numeric_limits::max_digits10, - bool force_inline = false) + bool no_comment = false, 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. @@ -666,7 +680,7 @@ format(const basic_value& v, std::size_t w = 80u, oss << v.comments(); oss << '\n'; // to split the file comment from the first element } - oss << visit(serializer(w, fprec, false), v); + oss << visit(serializer(w, fprec, no_comment, false), v); return oss.str(); } return visit(serializer(w, fprec, force_inline), v); @@ -712,15 +726,15 @@ operator<<(std::basic_ostream& os, const basic_value& v) // by defualt, iword is initialized byl 0. And by default, toml11 outputs // comments. So `0` means showcomment. 1 means nocommnet. - const bool show_comment = (0 == os.iword(detail::comment_index(os))); + const bool no_comment = (1 == os.iword(detail::comment_index(os))); - if(show_comment && v.is_table() && !v.comments().empty()) + if(!no_comment && v.is_table() && !v.comments().empty()) { os << v.comments(); os << '\n'; // to split the file comment from the first element } // the root object can't be an inline table. so pass `false`. - os << visit(serializer(w, fprec, false), v); + os << visit(serializer(w, fprec, false, no_comment), v); // if v is a non-table value, and has only one comment, then // put a comment just after a value. in the following way. @@ -739,7 +753,7 @@ operator<<(std::basic_ostream& os, const basic_value& v) // // In this case, it is impossible to put comments before key-value pair. // The only way to preserve comments is to put all of them after a value. - if(show_comment && !v.is_table() && !v.comments().empty()) + if(!no_comment && !v.is_table() && !v.comments().empty()) { os << " #"; for(const auto& c : v.comments()) {os << c;} From df0d870c97a4533da0441af61399d6f2facc9ec5 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 15:00:00 +0900 Subject: [PATCH 154/162] test: add test for serialization with nocomment --- tests/test_serialize_file.cpp | 81 ++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index 8c513a8..e0ab10d 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -11,6 +11,39 @@ #include #include +template class Table, + template class Array> +bool has_comment_inside(const toml::basic_value& v) +{ + if(!v.comments().empty()) + { + return false; + } + // v itself does not have a comment. + if(v.is_array()) + { + for(const auto& x : v.as_array()) + { + if(has_comment_inside(x)) + { + return false; + } + } + } + if(v.is_table()) + { + for(const auto& x : v.as_table()) + { + if(has_comment_inside(x.second)) + { + return false; + } + } + } + return true; +} + BOOST_AUTO_TEST_CASE(test_example) { const auto data = toml::parse("toml/tests/example.toml"); @@ -37,12 +70,12 @@ BOOST_AUTO_TEST_CASE(test_example_map_dq) const auto data = toml::parse( "toml/tests/example.toml"); { - std::ofstream ofs("tmp1.toml"); + std::ofstream ofs("tmp1_map_dq.toml"); ofs << std::setw(80) << data; } auto serialized = toml::parse( - "tmp1.toml"); + "tmp1_map_dq.toml"); { auto& owner = toml::find(serialized, "owner"); auto& bio = toml::find(owner, "bio"); @@ -80,17 +113,37 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment) } } +BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) +{ + { + const auto data = toml::parse("toml/tests/example.toml"); + { + std::ofstream ofs("tmp1_com_nocomment.toml"); + ofs << std::setw(80) << toml::nocomment << data; + } + const auto serialized = toml::parse("tmp1_com_nocomment.toml"); + // check no comment exist + BOOST_TEST(!has_comment_inside(serialized)); + } + { + const auto data_nocomment = toml::parse("toml/tests/example.toml"); + const auto serialized = toml::parse("tmp1_com_nocomment.toml"); + // check collectly serialized + BOOST_TEST(data_nocomment == serialized); + } +} + BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) { const auto data = toml::parse( "toml/tests/example.toml"); { - std::ofstream ofs("tmp1_com.toml"); + std::ofstream ofs("tmp1_com_map_dq.toml"); ofs << std::setw(80) << data; } auto serialized = toml::parse( - "tmp1_com.toml"); + "tmp1_com_map_dq.toml"); { auto& owner = toml::find(serialized, "owner"); auto& bio = toml::find(owner, "bio"); @@ -102,11 +155,29 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq) } BOOST_TEST(data == serialized); { - std::ofstream ofs("tmp1_com1.toml"); + std::ofstream ofs("tmp1_com1_map_dq.toml"); ofs << std::setw(80) << serialized; } } +BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) +{ + { + const auto data = toml::parse("toml/tests/example.toml"); + { + std::ofstream ofs("tmp1_com_map_dq_nocomment.toml"); + ofs << std::setw(80) << toml::nocomment << data; + } + const auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + BOOST_TEST(!has_comment_inside(serialized)); + } + { + const auto data_nocomment = toml::parse("toml/tests/example.toml"); + const auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + BOOST_TEST(data_nocomment == serialized); + } +} + BOOST_AUTO_TEST_CASE(test_fruit) { const auto data = toml::parse("toml/tests/fruit.toml"); From 0fc0967f6f9b36dc3bc839a876b7b6a9b11427ce Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 15:38:28 +0900 Subject: [PATCH 155/162] fix: remove CR before comparing to the reference --- tests/test_serialize_file.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/test_serialize_file.cpp b/tests/test_serialize_file.cpp index e0ab10d..f7384bb 100644 --- a/tests/test_serialize_file.cpp +++ b/tests/test_serialize_file.cpp @@ -127,7 +127,16 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_nocomment) } { const auto data_nocomment = toml::parse("toml/tests/example.toml"); - const auto serialized = toml::parse("tmp1_com_nocomment.toml"); + auto serialized = toml::parse("tmp1_com_nocomment.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } // check collectly serialized BOOST_TEST(data_nocomment == serialized); } @@ -173,7 +182,16 @@ BOOST_AUTO_TEST_CASE(test_example_with_comment_map_dq_nocomment) } { const auto data_nocomment = toml::parse("toml/tests/example.toml"); - const auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + auto serialized = toml::parse("tmp1_com_map_dq_nocomment.toml"); + { + auto& owner = toml::find(serialized, "owner"); + auto& bio = toml::find(owner, "bio"); + const auto CR = std::find(bio.begin(), bio.end(), '\r'); + if(CR != bio.end()) + { + bio.erase(CR); + } + } BOOST_TEST(data_nocomment == serialized); } } From c2721880609af3fb5a31027552d8794d5713c6e3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 16:39:54 +0900 Subject: [PATCH 156/162] fix: check inline table does not include LF --- toml/serializer.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toml/serializer.hpp b/toml/serializer.hpp index 0761b17..f1fa762 100644 --- a/toml/serializer.hpp +++ b/toml/serializer.hpp @@ -415,7 +415,8 @@ struct serializer token += " = "; } token += this->make_inline_table(v); - if(token.size() < this->width_) + if(token.size() < this->width_ && + token.end() == std::find(token.begin(), token.end(), '\n')) { return token; } From 299d1098e4c4e879d5d7fa8519b4d070c6bb198c Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 16:40:42 +0900 Subject: [PATCH 157/162] test: add serialization test for arbitrary file --- tests/check_serialization.cpp | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 tests/check_serialization.cpp diff --git a/tests/check_serialization.cpp b/tests/check_serialization.cpp new file mode 100644 index 0000000..3af0a37 --- /dev/null +++ b/tests/check_serialization.cpp @@ -0,0 +1,57 @@ +#include "toml.hpp" +#include +#include + +int main(int argc, char **argv) +{ + if(argc != 2) + { + std::cerr << "usage: ./check [filename]" << std::endl; + return 1; + } + + const std::string filename(argv[1]); + + { + const auto data = toml::parse(filename); + { + std::ofstream ofs("tmp.toml"); + ofs << std::setprecision(16) << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp.toml"); + + if(data != serialized) + { + std::cerr << "============================================================\n"; + std::cerr << "result (w/o comment) different: " << filename << std::endl; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# serialized\n"; + std::cerr << serialized; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# data\n"; + std::cerr << data; + return 1; + } + } + { + const auto data = toml::parse(filename); + { + std::ofstream ofs("tmp.toml"); + ofs << std::setprecision(16) << std::setw(80) << data; + } + const auto serialized = toml::parse("tmp.toml"); + if(data != serialized) + { + std::cerr << "============================================================\n"; + std::cerr << "result (w/ comment) different: " << filename << std::endl; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# serialized\n"; + std::cerr << serialized; + std::cerr << "------------------------------------------------------------\n"; + std::cerr << "# data\n"; + std::cerr << data; + return 1; + } + } + return 0; +} From 716f7bacbaf2649a3c2465090084f18bdce75a69 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 16:43:11 +0900 Subject: [PATCH 158/162] ci: run serialization test to circleci --- .circleci/config.yml | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 806e43f..d6f2820 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,6 +15,29 @@ jobs: 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 + test_serialization: + docker: + - image: circleci/buildpack-deps:bionic + steps: + - checkout + - run: + command: | + g++ --version + cd tests/ + g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -Werror -I../ check_serialization.cpp -o check_serialization + git clone https://github.com/BurntSushi/toml-test.git + cp check_serialization toml-test/tests/valid + cd toml-test/tests/valid + for f in $(ls ./*.toml); + do echo "==> ${f}"; + cat ${f}; + echo "---------------------------------------"; + ./check_serialization ${f} invalid; + if [ $? -ne 0 ] ; then + exit 1 + fi + echo "======================================="; + done output_result: docker: - image: circleci/buildpack-deps:bionic @@ -24,7 +47,7 @@ jobs: command: | g++ --version cd tests/ - g++ -std=c++11 -O2 -Wall -Wextra -Werror -I../ check.cpp -o check + g++ -std=c++11 -O2 -Wall -Wextra -Wpedantic -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 From e61b38fac2c7dde4571c43d534e2ca01fb168eb8 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 16:45:59 +0900 Subject: [PATCH 159/162] ci: add test_serialization to the jobs --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index d6f2820..9ec925c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -79,4 +79,5 @@ workflows: test: jobs: - test_suite + - test_serialization - output_result From 9b12b17d5e1430c663e6b8e9404c3757e44d14e3 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 17:36:16 +0900 Subject: [PATCH 160/162] ci: fix ci job script --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ec925c..2db5ab3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -32,7 +32,7 @@ jobs: do echo "==> ${f}"; cat ${f}; echo "---------------------------------------"; - ./check_serialization ${f} invalid; + ./check_serialization ${f}; if [ $? -ne 0 ] ; then exit 1 fi From c2435b0d5661e1b39eab034bbcbf9ad9f3b5094a Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 20:19:47 +0900 Subject: [PATCH 161/162] feat:boom:: format toml::string as TOML format --- toml/string.hpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/toml/string.hpp b/toml/string.hpp index abd58b5..98b355b 100644 --- a/toml/string.hpp +++ b/toml/string.hpp @@ -139,9 +139,74 @@ operator>=(const char* lhs, const string& rhs) {return std::string(lhs) >= rhs.s template std::basic_ostream& -operator<<(std::basic_ostream& os, const string& str) +operator<<(std::basic_ostream& os, const string& s) { - os << str.str; + if(s.kind == string_t::basic) + { + if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend()) + { + // it contains newline. make it multiline string. + os << "\"\"\"\n"; + for(auto i=s.str.cbegin(), e=s.str.cend(); i!=e; ++i) + { + switch(*i) + { + case '\\': {os << "\\\\"; break;} + case '\"': {os << "\\\""; break;} + case '\b': {os << "\\b"; break;} + case '\t': {os << "\\t"; break;} + case '\f': {os << "\\f"; break;} + case '\n': {os << '\n'; break;} + case '\r': + { + // since it is a multiline string, + // CRLF is not needed to be escaped. + if(std::next(i) != e && *std::next(i) == '\n') + { + os << "\r\n"; + ++i; + } + else + { + os << "\\r"; + } + break; + } + default: {os << *i; break;} + } + } + os << "\\\n\"\"\""; + return os; + } + // no newline. make it inline. + os << "\""; + for(const auto c : s.str) + { + switch(c) + { + case '\\': {os << "\\\\"; break;} + case '\"': {os << "\\\""; break;} + case '\b': {os << "\\b"; break;} + case '\t': {os << "\\t"; break;} + case '\f': {os << "\\f"; break;} + case '\n': {os << "\\n"; break;} + case '\r': {os << "\\r"; break;} + default : {os << c; break;} + } + } + os << "\""; + return os; + } + // 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() ) + { + // contains newline or single quote. make it multiline. + os << "'''\n" << s.str << "'''"; + return os; + } + // normal literal string + os << '\'' << s.str << '\''; return os; } From 2c192af35dea5d50209a649f88b14fa9599ae749 Mon Sep 17 00:00:00 2001 From: ToruNiina Date: Sat, 29 Jun 2019 20:20:31 +0900 Subject: [PATCH 162/162] test: add test for toml::string format --- tests/CMakeLists.txt | 1 + tests/test_string.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 tests/test_string.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 01d038c..b395c7a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,6 @@ set(TEST_NAMES test_datetime + test_string test_utility test_result test_traits diff --git a/tests/test_string.cpp b/tests/test_string.cpp new file mode 100644 index 0000000..f007bdf --- /dev/null +++ b/tests/test_string.cpp @@ -0,0 +1,113 @@ +#define BOOST_TEST_MODULE "test_string" +#include +#include + +BOOST_AUTO_TEST_CASE(test_basic_string) +{ + { + const toml::string str("basic string"); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const std::string s1 ("basic string"); + const toml::string str(s1); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const toml::string str("basic string", toml::string_t::basic); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } + { + const std::string s1 ("basic string"); + const toml::string str(s1, toml::string_t::basic); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "\"basic string\""); + } +} + +BOOST_AUTO_TEST_CASE(test_basic_ml_string) +{ + { + const toml::string str("basic\nstring"); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } + { + const std::string s1 ("basic\nstring"); + const toml::string str(s1); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } + { + const toml::string str("basic\nstring", toml::string_t::basic); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + + } + { + const std::string s1 ("basic\nstring"); + const toml::string str(s1, toml::string_t::basic); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "\"\"\"\nbasic\nstring\\\n\"\"\""; + BOOST_TEST(oss1.str() == oss2.str()); + } +} + + +BOOST_AUTO_TEST_CASE(test_literal_string) +{ + { + const toml::string str("literal string", toml::string_t::literal); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "'literal string'"); + } + { + const std::string s1 ("literal string"); + const toml::string str(s1, toml::string_t::literal); + std::ostringstream oss; + oss << str; + BOOST_TEST(oss.str() == "'literal string'"); + } +} + +BOOST_AUTO_TEST_CASE(test_literal_ml_string) +{ + { + const toml::string str("literal\nstring", toml::string_t::literal); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "'''\nliteral\nstring'''"; + BOOST_TEST(oss1.str() == oss2.str()); + + } + { + const std::string s1 ("literal\nstring"); + const toml::string str(s1, toml::string_t::literal); + std::ostringstream oss1; + oss1 << str; + std::ostringstream oss2; + oss2 << "'''\nliteral\nstring'''"; + BOOST_TEST(oss1.str() == oss2.str()); + } +} +