added ASan to CI (closes #123)

also:
- made all wrapped array and table iterator internal conversions explicit
- minor example code refactoring
This commit is contained in:
Mark Gillard 2021-11-25 20:20:22 +02:00
parent 307ebd1f47
commit ad4ae98af0
12 changed files with 167 additions and 124 deletions

View File

@ -23,7 +23,7 @@ jobs:
- run: - run:
name: Building and testing with clang name: Building and testing with clang
command: | command: |
CXX_LD=lld CXX=clang++ meson build --buildtype=debug -Dpedantic=true -Dbuild_tests=true -Dbuild_examples=true -Dgenerate_cmake_config=false -Db_lto=false CXX_LD=lld CXX=clang++ meson build --buildtype=debug -Dpedantic=true -Dbuild_tests=true -Dbuild_examples=true -Dgenerate_cmake_config=false -Db_lto=false -Dasan_examples=true
cd build && meson compile -j 4 && meson test --num-processes 1 --verbose cd build && meson compile -j 4 && meson test --num-processes 1 --verbose
release_clang: release_clang:
@ -39,7 +39,7 @@ jobs:
- run: - run:
name: Building and testing with clang name: Building and testing with clang
command: | command: |
CXX_LD=lld CXX=clang++ meson build --buildtype=release -Dpedantic=true -Dbuild_tests=true -Dbuild_examples=true -Dgenerate_cmake_config=false -Db_lto=false CXX_LD=lld CXX=clang++ meson build --buildtype=release -Dpedantic=true -Dbuild_tests=true -Dbuild_examples=true -Dgenerate_cmake_config=false -Db_lto=false -Dasan_examples=true
cd build && meson compile -j 4 && meson test --num-processes 1 --verbose cd build && meson compile -j 4 && meson test --num-processes 1 --verbose
debug_gcc: debug_gcc:

View File

@ -1,8 +1,14 @@
example_args = [] example_args = []
example_args += additional_arguments example_args += additional_arguments
example_overrides = []
example_overrides += overrides
if is_gcc or is_clang if is_gcc or is_clang
example_args += [ '-Wno-switch', '-Wno-switch-default', '-Wno-switch-enum' ] example_args += [ '-Wno-switch', '-Wno-switch-default', '-Wno-switch-enum' ]
endif endif
if is_clang and get_option('asan_examples')
example_args += [ '-g3' ]
example_overrides += 'b_sanitize=address'
endif
examples = [ examples = [
'simple_parser', 'simple_parser',
@ -12,12 +18,29 @@ examples = [
'parse_benchmark', 'parse_benchmark',
] ]
example_executables = []
foreach example : examples foreach example : examples
executable( example_executables += [[
example, example,
[ example+'.cpp' ], executable(
include_directories: include_dirs, example,
cpp_args: example_args, [ example+'.cpp' ],
override_options: overrides include_directories: include_dirs,
) cpp_args: example_args,
override_options: example_overrides
)
]]
endforeach endforeach
if is_clang and get_option('asan_examples')
foreach executable : example_executables
if executable[0].contains('transcoder') # skip the transcoder because it waits on stdin
continue
endif
test(
executable[0], # name
executable[1], # executable object
workdir: meson.source_root()/'examples'
)
endforeach
endif

View File

@ -3,7 +3,7 @@
// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. // See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text.
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
// This example demonstrates how to parse TOML from a file and re-serialize it (print it out) to stdout. // This example demonstrates how to parse TOML from a file or stdin and re-serialize it (print it out) to stdout.
#include "examples.h" #include "examples.h"
@ -15,15 +15,24 @@ using namespace std::string_view_literals;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
const auto path = argc > 1 ? std::string_view{ argv[1] } : "example.toml"sv; const auto path = argc > 1 ? std::string_view{ argv[1] } : "example.toml"sv;
toml::table table;
try try
{ {
const auto table = toml::parse_file(path); // read directly from stdin
std::cout << table << "\n"; if (path == "-"sv || path.empty())
table = toml::parse(std::cin, "stdin"sv);
// read from a file
else
table = toml::parse_file(path);
} }
catch (const toml::parse_error& err) catch (const toml::parse_error& err)
{ {
std::cerr << err << "\n"; std::cerr << err << "\n";
return 1; return 1;
} }
std::cout << table << "\n";
return 0; return 0;
} }

View File

@ -14,18 +14,18 @@ using namespace std::string_view_literals;
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
const auto path = argc > 1 ? std::string_view{ argv[1] } : ""sv;
toml::table table; toml::table table;
try try
{ {
// read from a file if a path argument is given // read directly from stdin
if (argc > 1) if (path == "-"sv || path.empty())
table = toml::parse_file(argv[1]);
// otherwise read directly from stdin
else
table = toml::parse(std::cin, "stdin"sv); table = toml::parse(std::cin, "stdin"sv);
std::cout << toml::json_formatter{ table } << "\n"; // read from a file
else
table = toml::parse_file(argv[1]);
} }
catch (const toml::parse_error& err) catch (const toml::parse_error& err)
{ {

View File

@ -38,13 +38,13 @@ TOML_IMPL_NAMESPACE_START
array_iterator() noexcept = default; array_iterator() noexcept = default;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
array_iterator(mutable_vector_iterator iter) noexcept // explicit array_iterator(mutable_vector_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
array_iterator(const_vector_iterator iter) noexcept // explicit array_iterator(const_vector_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
@ -98,14 +98,14 @@ TOML_IMPL_NAMESPACE_START
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const vector_iterator&() const noexcept explicit operator const vector_iterator&() const noexcept
{ {
return iter_; return iter_;
} }
TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const const_vector_iterator() const noexcept explicit operator const const_vector_iterator() const noexcept
{ {
return iter_; return iter_;
} }
@ -125,19 +125,19 @@ TOML_IMPL_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept
{ {
return lhs.iter_ + rhs; return array_iterator{ lhs.iter_ + rhs };
} }
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept
{ {
return rhs.iter_ + lhs; return array_iterator{ rhs.iter_ + lhs };
} }
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept
{ {
return lhs.iter_ - rhs; return array_iterator{ lhs.iter_ - rhs };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
@ -798,42 +798,42 @@ TOML_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
iterator begin() noexcept iterator begin() noexcept
{ {
return elems_.begin(); return iterator{ elems_.begin() };
} }
/// \brief Returns an iterator to the first element. /// \brief Returns an iterator to the first element.
TOML_NODISCARD TOML_NODISCARD
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ {
return elems_.cbegin(); return const_iterator{ elems_.cbegin() };
} }
/// \brief Returns an iterator to the first element. /// \brief Returns an iterator to the first element.
TOML_NODISCARD TOML_NODISCARD
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ {
return elems_.cbegin(); return const_iterator{ elems_.cbegin() };
} }
/// \brief Returns an iterator to one-past-the-last element. /// \brief Returns an iterator to one-past-the-last element.
TOML_NODISCARD TOML_NODISCARD
iterator end() noexcept iterator end() noexcept
{ {
return elems_.end(); return iterator{ elems_.end() };
} }
/// \brief Returns an iterator to one-past-the-last element. /// \brief Returns an iterator to one-past-the-last element.
TOML_NODISCARD TOML_NODISCARD
const_iterator end() const noexcept const_iterator end() const noexcept
{ {
return elems_.cend(); return const_iterator{ elems_.cend() };
} }
/// \brief Returns an iterator to one-past-the-last element. /// \brief Returns an iterator to one-past-the-last element.
TOML_NODISCARD TOML_NODISCARD
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ {
return elems_.cend(); return const_iterator{ elems_.cend() };
} }
/// @} /// @}
@ -1102,7 +1102,8 @@ TOML_NAMESPACE_START
if (!val) if (!val)
return end(); return end();
} }
return insert_at(pos, impl::make_node(static_cast<ElemType&&>(val), flags)); return iterator{ insert_at(const_vector_iterator{ pos },
impl::make_node(static_cast<ElemType&&>(val), flags)) };
} }
/// \brief Repeatedly inserts a new element starting at a specific position in the array. /// \brief Repeatedly inserts a new element starting at a specific position in the array.
@ -1155,11 +1156,11 @@ TOML_NAMESPACE_START
} }
switch (count) switch (count)
{ {
case 0: return elems_.begin() + (pos - elems_.cbegin()); case 0: return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
case 1: return insert(pos, static_cast<ElemType&&>(val), flags); case 1: return insert(pos, static_cast<ElemType&&>(val), flags);
default: default:
{ {
const auto start_idx = static_cast<size_t>(pos - elems_.cbegin()); const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
preinsertion_resize(start_idx, count); preinsertion_resize(start_idx, count);
size_t i = start_idx; size_t i = start_idx;
for (size_t e = start_idx + count - 1u; i < e; i++) for (size_t e = start_idx + count - 1u; i < e; i++)
@ -1167,7 +1168,7 @@ TOML_NAMESPACE_START
//# potentially move the initial value into the last element //# potentially move the initial value into the last element
elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags); elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags);
return elems_.begin() + static_cast<ptrdiff_t>(start_idx); return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
} }
} }
} }
@ -1191,7 +1192,7 @@ TOML_NAMESPACE_START
{ {
const auto distance = std::distance(first, last); const auto distance = std::distance(first, last);
if (distance <= 0) if (distance <= 0)
return elems_.begin() + (pos - elems_.cbegin()); return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
else else
{ {
auto count = distance; auto count = distance;
@ -1202,9 +1203,9 @@ TOML_NAMESPACE_START
if (!(*it)) if (!(*it))
count--; count--;
if (!count) if (!count)
return elems_.begin() + (pos - elems_.cbegin()); return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
} }
const auto start_idx = static_cast<size_t>(pos - elems_.cbegin()); const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
preinsertion_resize(start_idx, static_cast<size_t>(count)); preinsertion_resize(start_idx, static_cast<size_t>(count));
size_t i = start_idx; size_t i = start_idx;
for (auto it = first; it != last; it++) for (auto it = first; it != last; it++)
@ -1219,7 +1220,7 @@ TOML_NAMESPACE_START
else else
elems_[i++] = impl::make_node(*it, flags); elems_[i++] = impl::make_node(*it, flags);
} }
return elems_.begin() + static_cast<ptrdiff_t>(start_idx); return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
} }
} }
@ -1275,7 +1276,8 @@ TOML_NAMESPACE_START
static_assert((impl::is_native<type> || impl::is_one_of<type, table, array>)&&!impl::is_cvref<type>, static_assert((impl::is_native<type> || impl::is_one_of<type, table, array>)&&!impl::is_cvref<type>,
"Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST); "Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
return insert_at(pos, impl::node_ptr{ new impl::wrap_node<type>{ static_cast<Args&&>(args)... } }); return iterator{ insert_at(const_vector_iterator{ pos },
impl::node_ptr{ new impl::wrap_node<type>{ static_cast<Args&&>(args)... } }) };
} }
/// \brief Replaces the element at a specific position in the array with a different value. /// \brief Replaces the element at a specific position in the array with a different value.
@ -1316,9 +1318,9 @@ TOML_NAMESPACE_START
return end(); return end();
} }
const auto it = elems_.begin() + (pos - elems_.cbegin()); const auto it = elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin());
*it = impl::make_node(static_cast<ElemType&&>(val), flags); *it = impl::make_node(static_cast<ElemType&&>(val), flags);
return it; return iterator{ it };
} }
/// \brief Appends a new element to the end of the array. /// \brief Appends a new element to the end of the array.

View File

@ -207,13 +207,13 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
array::iterator array::erase(const_iterator pos) noexcept array::iterator array::erase(const_iterator pos) noexcept
{ {
return elems_.erase(pos); return iterator{ elems_.erase(const_vector_iterator{ pos }) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
array::iterator array::erase(const_iterator first, const_iterator last) noexcept array::iterator array::erase(const_iterator first, const_iterator last) noexcept
{ {
return elems_.erase(first, last); return iterator{ elems_.erase(const_vector_iterator{ first }, const_vector_iterator{ last }) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE

View File

@ -58,13 +58,13 @@ TOML_IMPL_NAMESPACE_START
table_iterator() noexcept = default; table_iterator() noexcept = default;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
table_iterator(mutable_map_iterator iter) noexcept // explicit table_iterator(mutable_map_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
table_iterator(const_map_iterator iter) noexcept // explicit table_iterator(const_map_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
@ -135,14 +135,14 @@ TOML_IMPL_NAMESPACE_START
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const map_iterator&() const noexcept explicit operator const map_iterator&() const noexcept
{ {
return iter_; return iter_;
} }
TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const const_map_iterator() const noexcept explicit operator const const_map_iterator() const noexcept
{ {
return iter_; return iter_;
} }
@ -783,42 +783,42 @@ TOML_NAMESPACE_START
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
iterator begin() noexcept iterator begin() noexcept
{ {
return map_.begin(); return iterator{ map_.begin() };
} }
/// \brief Returns an iterator to the first key-value pair. /// \brief Returns an iterator to the first key-value pair.
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ {
return map_.cbegin(); return const_iterator{ map_.cbegin() };
} }
/// \brief Returns an iterator to the first key-value pair. /// \brief Returns an iterator to the first key-value pair.
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ {
return map_.cbegin(); return const_iterator{ map_.cbegin() };
} }
/// \brief Returns an iterator to one-past-the-last key-value pair. /// \brief Returns an iterator to one-past-the-last key-value pair.
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
iterator end() noexcept iterator end() noexcept
{ {
return map_.end(); return iterator{ map_.end() };
} }
/// \brief Returns an iterator to one-past-the-last key-value pair. /// \brief Returns an iterator to one-past-the-last key-value pair.
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator end() const noexcept const_iterator end() const noexcept
{ {
return map_.cend(); return const_iterator{ map_.cend() };
} }
/// \brief Returns an iterator to one-past-the-last key-value pair. /// \brief Returns an iterator to one-past-the-last key-value pair.
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ {
return map_.cend(); return const_iterator{ map_.cend() };
} }
/// @} /// @}
@ -861,7 +861,7 @@ TOML_NAMESPACE_START
TOML_PURE_GETTER TOML_PURE_GETTER
iterator lower_bound(std::string_view key) noexcept iterator lower_bound(std::string_view key) noexcept
{ {
return get_lower_bound(key); return iterator{ get_lower_bound(key) };
} }
/// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than the given key. /// \brief Returns a const iterator to the first key-value pair with key that is _not less_ than the given key.
@ -870,7 +870,7 @@ TOML_NAMESPACE_START
TOML_PURE_GETTER TOML_PURE_GETTER
const_iterator lower_bound(std::string_view key) const noexcept const_iterator lower_bound(std::string_view key) const noexcept
{ {
return const_cast<table&>(*this).get_lower_bound(key); return const_iterator{ const_cast<table&>(*this).get_lower_bound(key) };
} }
#if TOML_ENABLE_WINDOWS_COMPAT #if TOML_ENABLE_WINDOWS_COMPAT
@ -1013,7 +1013,7 @@ TOML_NAMESPACE_START
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair. /// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
iterator erase(iterator pos) noexcept iterator erase(iterator pos) noexcept
{ {
return erase(const_map_iterator{ pos }); return iterator{ erase(const_map_iterator{ pos }) };
} }
/// \brief Removes the specified key-value pair from the table (const iterator overload). /// \brief Removes the specified key-value pair from the table (const iterator overload).
@ -1040,7 +1040,7 @@ TOML_NAMESPACE_START
/// \returns Iterator to the first key-value pair immediately following the removed key-value pair. /// \returns Iterator to the first key-value pair immediately following the removed key-value pair.
iterator erase(const_iterator pos) noexcept iterator erase(const_iterator pos) noexcept
{ {
return erase(const_map_iterator{ pos }); return iterator{ erase(const_map_iterator{ pos }) };
} }
/// \brief Removes the key-value pairs in the range [first, last) from the table. /// \brief Removes the key-value pairs in the range [first, last) from the table.
@ -1069,7 +1069,7 @@ TOML_NAMESPACE_START
/// \returns Iterator to the first key-value pair immediately following the last removed key-value pair. /// \returns Iterator to the first key-value pair immediately following the last removed key-value pair.
iterator erase(const_iterator begin, const_iterator end) noexcept iterator erase(const_iterator begin, const_iterator end) noexcept
{ {
return erase(const_map_iterator{ begin }, const_map_iterator{ end }); return iterator{ erase(const_map_iterator{ begin }, const_map_iterator{ end }) };
} }
/// \brief Removes the value with the given key from the table. /// \brief Removes the value with the given key from the table.
@ -1242,7 +1242,7 @@ TOML_NAMESPACE_START
#endif #endif
} }
} }
return ipos; return iterator{ ipos };
} }
} }
@ -1328,7 +1328,7 @@ TOML_NAMESPACE_START
map_iterator ipos = get_lower_bound(key_view); map_iterator ipos = get_lower_bound(key_view);
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint(ipos, ipos = insert_with_hint(const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::make_node(static_cast<ValueType&&>(val), flags)); impl::make_node(static_cast<ValueType&&>(val), flags));
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };
@ -1475,7 +1475,7 @@ TOML_NAMESPACE_START
map_iterator ipos = get_lower_bound(key_view); map_iterator ipos = get_lower_bound(key_view);
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint(ipos, ipos = insert_with_hint(const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::make_node(static_cast<ValueType&&>(val), flags)); impl::make_node(static_cast<ValueType&&>(val), flags));
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };
@ -1557,7 +1557,7 @@ TOML_NAMESPACE_START
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint( ipos = insert_with_hint(
ipos, const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::node_ptr{ new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... } }); impl::node_ptr{ new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... } });
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };

View File

@ -181,13 +181,13 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::iterator table::find(std::string_view key) noexcept table::iterator table::find(std::string_view key) noexcept
{ {
return map_.find(key); return iterator{ map_.find(key) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::const_iterator table::find(std::string_view key) const noexcept table::const_iterator table::find(std::string_view key) const noexcept
{ {
return map_.find(key); return const_iterator{ map_.find(key) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
@ -258,7 +258,7 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::map_iterator table::insert_with_hint(const_iterator hint, key && k, impl::node_ptr && v) table::map_iterator table::insert_with_hint(const_iterator hint, key && k, impl::node_ptr && v)
{ {
return map_.emplace_hint(hint, std::move(k), std::move(v)); return map_.emplace_hint(const_map_iterator{ hint }, std::move(k), std::move(v));
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE

View File

@ -156,12 +156,6 @@ if is_clang
if get_option('time_trace') if get_option('time_trace')
add_project_arguments('-ftime-trace', language: 'cpp') add_project_arguments('-ftime-trace', language: 'cpp')
endif endif
if is_release
add_project_arguments(
'-fmerge-all-constants',
language: 'cpp'
)
endif
endif endif
# MSVC or icc-cl # MSVC or icc-cl

View File

@ -3,3 +3,6 @@ option('build_examples', type: 'boolean', value: false, description: 'Build exa
option('generate_cmake_config', type: 'boolean', value: true, description: 'Generate a cmake package config file (default: true - no effect when included as a subproject)') option('generate_cmake_config', type: 'boolean', value: true, description: 'Generate a cmake package config file (default: true - no effect when included as a subproject)')
option('pedantic', type: 'boolean', value: false, description: 'Enable as many compiler warnings as possible (default: false)') option('pedantic', type: 'boolean', value: false, description: 'Enable as many compiler warnings as possible (default: false)')
option('time_trace', type: 'boolean', value: false, description: 'Enable the -ftime-trace option (Clang only)') option('time_trace', type: 'boolean', value: false, description: 'Enable the -ftime-trace option (Clang only)')
option('asan_examples', type: 'boolean', value: false)
option('asan_tests', type: 'boolean', value: false)

View File

@ -77,6 +77,10 @@ foreach cpp20 : cpp20_modes
test_args = [] test_args = []
test_args += additional_arguments test_args += additional_arguments
single_header = (counter % 2 == 1)
tl_optional = (counter % 4 == 2 and exceptions)
address_sanitizer = (is_clang and not (single_header or tl_optional or fast_math)) and get_option('asan_tests')
if cpp20 if cpp20
test_name = 'cpp20' test_name = 'cpp20'
test_overrides += 'cpp_std=none' test_overrides += 'cpp_std=none'
@ -103,6 +107,11 @@ foreach cpp20 : cpp20_modes
endif endif
endif endif
if address_sanitizer
test_args += [ '-g3' ]
test_overrides += 'b_sanitize=address'
endif
if fast_math if fast_math
test_name = test_name + '_fastmath' test_name = test_name + '_fastmath'
test_args += compiler_supports_fast_math_args test_args += compiler_supports_fast_math_args
@ -130,14 +139,14 @@ foreach cpp20 : cpp20_modes
test_args += '-DTOML_ENABLE_UNRELEASED_FEATURES=0' test_args += '-DTOML_ENABLE_UNRELEASED_FEATURES=0'
endif endif
if counter % 2 == 1 if single_header
test_args += '-DUSE_SINGLE_HEADER=1' test_args += '-DUSE_SINGLE_HEADER=1'
endif endif
if counter % 4 == 2 and exceptions if tl_optional
test_args += '-DUSE_TARTANLLAMA_OPTIONAL=1' test_args += '-DUSE_TARTANLLAMA_OPTIONAL=1'
test_name = test_name + '_tlopt' test_name = test_name + '_tlopt'
endif endif
test_executables += [[ test_executables += [[
test_name, test_name,
executable( executable(
@ -171,7 +180,8 @@ locales = [
foreach executable : test_executables foreach executable : test_executables
foreach locale : locales foreach locale : locales
test( test(
executable[0] + ' (' + locale + ')', executable[1], executable[0] + ' (' + locale + ')', # name
executable[1], # executable object
env: ['LC_ALL=' + locale], env: ['LC_ALL=' + locale],
workdir: meson.source_root()/'tests' workdir: meson.source_root()/'tests'
) )

View File

@ -4946,13 +4946,13 @@ TOML_IMPL_NAMESPACE_START
array_iterator() noexcept = default; array_iterator() noexcept = default;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
array_iterator(mutable_vector_iterator iter) noexcept // explicit array_iterator(mutable_vector_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
array_iterator(const_vector_iterator iter) noexcept // explicit array_iterator(const_vector_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
@ -5006,14 +5006,14 @@ TOML_IMPL_NAMESPACE_START
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const vector_iterator&() const noexcept explicit operator const vector_iterator&() const noexcept
{ {
return iter_; return iter_;
} }
TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const const_vector_iterator() const noexcept explicit operator const const_vector_iterator() const noexcept
{ {
return iter_; return iter_;
} }
@ -5033,19 +5033,19 @@ TOML_IMPL_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept friend array_iterator operator+(const array_iterator& lhs, ptrdiff_t rhs) noexcept
{ {
return lhs.iter_ + rhs; return array_iterator{ lhs.iter_ + rhs };
} }
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept friend array_iterator operator+(ptrdiff_t lhs, const array_iterator& rhs) noexcept
{ {
return rhs.iter_ + lhs; return array_iterator{ rhs.iter_ + lhs };
} }
TOML_NODISCARD TOML_NODISCARD
friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept friend array_iterator operator-(const array_iterator& lhs, ptrdiff_t rhs) noexcept
{ {
return lhs.iter_ - rhs; return array_iterator{ lhs.iter_ - rhs };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
@ -5503,37 +5503,37 @@ TOML_NAMESPACE_START
TOML_NODISCARD TOML_NODISCARD
iterator begin() noexcept iterator begin() noexcept
{ {
return elems_.begin(); return iterator{ elems_.begin() };
} }
TOML_NODISCARD TOML_NODISCARD
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ {
return elems_.cbegin(); return const_iterator{ elems_.cbegin() };
} }
TOML_NODISCARD TOML_NODISCARD
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ {
return elems_.cbegin(); return const_iterator{ elems_.cbegin() };
} }
TOML_NODISCARD TOML_NODISCARD
iterator end() noexcept iterator end() noexcept
{ {
return elems_.end(); return iterator{ elems_.end() };
} }
TOML_NODISCARD TOML_NODISCARD
const_iterator end() const noexcept const_iterator end() const noexcept
{ {
return elems_.cend(); return const_iterator{ elems_.cend() };
} }
TOML_NODISCARD TOML_NODISCARD
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ {
return elems_.cend(); return const_iterator{ elems_.cend() };
} }
TOML_NODISCARD TOML_NODISCARD
@ -5621,7 +5621,8 @@ TOML_NAMESPACE_START
if (!val) if (!val)
return end(); return end();
} }
return insert_at(pos, impl::make_node(static_cast<ElemType&&>(val), flags)); return iterator{ insert_at(const_vector_iterator{ pos },
impl::make_node(static_cast<ElemType&&>(val), flags)) };
} }
template <typename ElemType> template <typename ElemType>
@ -5637,18 +5638,18 @@ TOML_NAMESPACE_START
} }
switch (count) switch (count)
{ {
case 0: return elems_.begin() + (pos - elems_.cbegin()); case 0: return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
case 1: return insert(pos, static_cast<ElemType&&>(val), flags); case 1: return insert(pos, static_cast<ElemType&&>(val), flags);
default: default:
{ {
const auto start_idx = static_cast<size_t>(pos - elems_.cbegin()); const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
preinsertion_resize(start_idx, count); preinsertion_resize(start_idx, count);
size_t i = start_idx; size_t i = start_idx;
for (size_t e = start_idx + count - 1u; i < e; i++) for (size_t e = start_idx + count - 1u; i < e; i++)
elems_[i] = impl::make_node(val, flags); elems_[i] = impl::make_node(val, flags);
elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags); elems_[i] = impl::make_node(static_cast<ElemType&&>(val), flags);
return elems_.begin() + static_cast<ptrdiff_t>(start_idx); return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
} }
} }
} }
@ -5658,7 +5659,7 @@ TOML_NAMESPACE_START
{ {
const auto distance = std::distance(first, last); const auto distance = std::distance(first, last);
if (distance <= 0) if (distance <= 0)
return elems_.begin() + (pos - elems_.cbegin()); return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
else else
{ {
auto count = distance; auto count = distance;
@ -5669,9 +5670,9 @@ TOML_NAMESPACE_START
if (!(*it)) if (!(*it))
count--; count--;
if (!count) if (!count)
return elems_.begin() + (pos - elems_.cbegin()); return iterator{ elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin()) };
} }
const auto start_idx = static_cast<size_t>(pos - elems_.cbegin()); const auto start_idx = static_cast<size_t>(const_vector_iterator{ pos } - elems_.cbegin());
preinsertion_resize(start_idx, static_cast<size_t>(count)); preinsertion_resize(start_idx, static_cast<size_t>(count));
size_t i = start_idx; size_t i = start_idx;
for (auto it = first; it != last; it++) for (auto it = first; it != last; it++)
@ -5686,7 +5687,7 @@ TOML_NAMESPACE_START
else else
elems_[i++] = impl::make_node(*it, flags); elems_[i++] = impl::make_node(*it, flags);
} }
return elems_.begin() + static_cast<ptrdiff_t>(start_idx); return iterator{ elems_.begin() + static_cast<ptrdiff_t>(start_idx) };
} }
} }
@ -5705,7 +5706,8 @@ TOML_NAMESPACE_START
static_assert((impl::is_native<type> || impl::is_one_of<type, table, array>)&&!impl::is_cvref<type>, static_assert((impl::is_native<type> || impl::is_one_of<type, table, array>)&&!impl::is_cvref<type>,
"Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST); "Emplacement type parameter must be one of:" TOML_SA_UNWRAPPED_NODE_TYPE_LIST);
return insert_at(pos, impl::node_ptr{ new impl::wrap_node<type>{ static_cast<Args&&>(args)... } }); return iterator{ insert_at(const_vector_iterator{ pos },
impl::node_ptr{ new impl::wrap_node<type>{ static_cast<Args&&>(args)... } }) };
} }
template <typename ElemType> template <typename ElemType>
@ -5719,9 +5721,9 @@ TOML_NAMESPACE_START
return end(); return end();
} }
const auto it = elems_.begin() + (pos - elems_.cbegin()); const auto it = elems_.begin() + (const_vector_iterator{ pos } - elems_.cbegin());
*it = impl::make_node(static_cast<ElemType&&>(val), flags); *it = impl::make_node(static_cast<ElemType&&>(val), flags);
return it; return iterator{ it };
} }
template <typename ElemType> template <typename ElemType>
@ -6142,13 +6144,13 @@ TOML_IMPL_NAMESPACE_START
table_iterator() noexcept = default; table_iterator() noexcept = default;
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
table_iterator(mutable_map_iterator iter) noexcept // explicit table_iterator(mutable_map_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(C, bool C = IsConst)
TOML_NODISCARD_CTOR TOML_NODISCARD_CTOR
table_iterator(const_map_iterator iter) noexcept // explicit table_iterator(const_map_iterator iter) noexcept //
: iter_{ iter } : iter_{ iter }
{} {}
@ -6219,14 +6221,14 @@ TOML_IMPL_NAMESPACE_START
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const map_iterator&() const noexcept explicit operator const map_iterator&() const noexcept
{ {
return iter_; return iter_;
} }
TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst) TOML_CONSTRAINED_TEMPLATE(!C, bool C = IsConst)
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
operator const const_map_iterator() const noexcept explicit operator const const_map_iterator() const noexcept
{ {
return iter_; return iter_;
} }
@ -6642,37 +6644,37 @@ TOML_NAMESPACE_START
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
iterator begin() noexcept iterator begin() noexcept
{ {
return map_.begin(); return iterator{ map_.begin() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator begin() const noexcept const_iterator begin() const noexcept
{ {
return map_.cbegin(); return const_iterator{ map_.cbegin() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator cbegin() const noexcept const_iterator cbegin() const noexcept
{ {
return map_.cbegin(); return const_iterator{ map_.cbegin() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
iterator end() noexcept iterator end() noexcept
{ {
return map_.end(); return iterator{ map_.end() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator end() const noexcept const_iterator end() const noexcept
{ {
return map_.cend(); return const_iterator{ map_.cend() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
const_iterator cend() const noexcept const_iterator cend() const noexcept
{ {
return map_.cend(); return const_iterator{ map_.cend() };
} }
TOML_PURE_INLINE_GETTER TOML_PURE_INLINE_GETTER
@ -6698,13 +6700,13 @@ TOML_NAMESPACE_START
TOML_PURE_GETTER TOML_PURE_GETTER
iterator lower_bound(std::string_view key) noexcept iterator lower_bound(std::string_view key) noexcept
{ {
return get_lower_bound(key); return iterator{ get_lower_bound(key) };
} }
TOML_PURE_GETTER TOML_PURE_GETTER
const_iterator lower_bound(std::string_view key) const noexcept const_iterator lower_bound(std::string_view key) const noexcept
{ {
return const_cast<table&>(*this).get_lower_bound(key); return const_iterator{ const_cast<table&>(*this).get_lower_bound(key) };
} }
#if TOML_ENABLE_WINDOWS_COMPAT #if TOML_ENABLE_WINDOWS_COMPAT
@ -6780,17 +6782,17 @@ TOML_NAMESPACE_START
iterator erase(iterator pos) noexcept iterator erase(iterator pos) noexcept
{ {
return erase(const_map_iterator{ pos }); return iterator{ erase(const_map_iterator{ pos }) };
} }
iterator erase(const_iterator pos) noexcept iterator erase(const_iterator pos) noexcept
{ {
return erase(const_map_iterator{ pos }); return iterator{ erase(const_map_iterator{ pos }) };
} }
iterator erase(const_iterator begin, const_iterator end) noexcept iterator erase(const_iterator begin, const_iterator end) noexcept
{ {
return erase(const_map_iterator{ begin }, const_map_iterator{ end }); return iterator{ erase(const_map_iterator{ begin }, const_map_iterator{ end }) };
} }
TOML_API TOML_API
@ -6887,7 +6889,7 @@ TOML_NAMESPACE_START
#endif #endif
} }
} }
return ipos; return iterator{ ipos };
} }
} }
@ -6922,7 +6924,7 @@ TOML_NAMESPACE_START
map_iterator ipos = get_lower_bound(key_view); map_iterator ipos = get_lower_bound(key_view);
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint(ipos, ipos = insert_with_hint(const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::make_node(static_cast<ValueType&&>(val), flags)); impl::make_node(static_cast<ValueType&&>(val), flags));
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };
@ -6978,7 +6980,7 @@ TOML_NAMESPACE_START
map_iterator ipos = get_lower_bound(key_view); map_iterator ipos = get_lower_bound(key_view);
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint(ipos, ipos = insert_with_hint(const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::make_node(static_cast<ValueType&&>(val), flags)); impl::make_node(static_cast<ValueType&&>(val), flags));
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };
@ -7023,7 +7025,7 @@ TOML_NAMESPACE_START
if (ipos == map_.end() || ipos->first != key_view) if (ipos == map_.end() || ipos->first != key_view)
{ {
ipos = insert_with_hint( ipos = insert_with_hint(
ipos, const_iterator{ ipos },
toml::key{ static_cast<KeyType&&>(key) }, toml::key{ static_cast<KeyType&&>(key) },
impl::node_ptr{ new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... } }); impl::node_ptr{ new impl::wrap_node<unwrapped_type>{ static_cast<ValueArgs&&>(args)... } });
return { iterator{ ipos }, true }; return { iterator{ ipos }, true };
@ -10015,13 +10017,13 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
array::iterator array::erase(const_iterator pos) noexcept array::iterator array::erase(const_iterator pos) noexcept
{ {
return elems_.erase(pos); return iterator{ elems_.erase(const_vector_iterator{ pos }) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
array::iterator array::erase(const_iterator first, const_iterator last) noexcept array::iterator array::erase(const_iterator first, const_iterator last) noexcept
{ {
return elems_.erase(first, last); return iterator{ elems_.erase(const_vector_iterator{ first }, const_vector_iterator{ last }) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
@ -10349,13 +10351,13 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::iterator table::find(std::string_view key) noexcept table::iterator table::find(std::string_view key) noexcept
{ {
return map_.find(key); return iterator{ map_.find(key) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::const_iterator table::find(std::string_view key) const noexcept table::const_iterator table::find(std::string_view key) const noexcept
{ {
return map_.find(key); return const_iterator{ map_.find(key) };
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
@ -10426,7 +10428,7 @@ TOML_NAMESPACE_START
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE
table::map_iterator table::insert_with_hint(const_iterator hint, key && k, impl::node_ptr && v) table::map_iterator table::insert_with_hint(const_iterator hint, key && k, impl::node_ptr && v)
{ {
return map_.emplace_hint(hint, std::move(k), std::move(v)); return map_.emplace_hint(const_map_iterator{ hint }, std::move(k), std::move(v));
} }
TOML_EXTERNAL_LINKAGE TOML_EXTERNAL_LINKAGE