Skip to content

Commit

Permalink
fixed potential ODR issues relating to exception mode handling (fixes #6
Browse files Browse the repository at this point in the history
)

also:
- fixed truncation of floating-point values when using ostreams
- fixed some minor documentation issues (fixes #8)
- fixed missing value deduction guides for dates and times
- added serialization round-trip tests (closes #9)
- added node::is_number()
- added node_view::is_number()
- added node_view::value_or() (closes #7)
- added hexfloat parsing support for all implementations, not just <charconv> ones
  • Loading branch information
marzer committed Feb 22, 2020
1 parent 2219fd2 commit 3d653de
Show file tree
Hide file tree
Showing 24 changed files with 449 additions and 184 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
[![GitHub](https://img.shields.io/github/license/marzer/tomlplusplus)](https://github.com/marzer/tomlplusplus/blob/master/LICENSE)

`toml++` is a header-only toml parser and serializer for C++17, C++20 and whatever comes after.
- Fully [TOML v0.5.0]-compliant
- Modern C++17 (with some C++20 features where supported)
- Proper UTF-8 handling (incl. BOM)
- Works with or without exceptions
- Doesn't require RTTI
- First-class support for serializing to JSON
- Supports a number of 'unreleased' TOML features (optional)

<br>

Expand All @@ -25,10 +32,10 @@ Reading it in C++ is easy with `toml++`:
auto config = toml::parse_file( "configuration.toml" );

// get key-value pairs
std::string_view library_name = config["library"]["name"].as_string()->get();
std::string_view library_version = config["library"]["version"].as_string()->get();
std::string_view library_author = config["library"]["authors"][0].as_string()->get();
int64_t depends_on_cpp_version = config["dependencies"]["cpp"].as_integer()->get();
std::string_view library_name = config["library"]["name"].value_or(""sv);
std::string_view library_version = config["library"]["version"].value_or(""sv);
std::string_view library_author = config["library"]["authors"][0].value_or(""sv);
int64_t depends_on_cpp_version = config["dependencies"]["cpp"].value_or(0);

// modify the data
config.insert_or_assign("alternatives", toml::array{
Expand Down Expand Up @@ -80,7 +87,7 @@ won't need to mess with these at all, butif you do, set them before including to
| Option | Type | Default | Description |
|----------------------------|:--------------:|-----------------------------------|----------------------------------------------------------------------------------------------------------|
| `TOML_ASSERT(expr)` | function macro | `assert(expr)`<br>(or undefined) | Sets the assert function used by the library. |
| `TOML_CHAR_8_STRINGS` | boolean | `0` | Uses C++20 [char8_t]-based strings as the toml string data type. |
| `TOML_CHAR_8_STRINGS` | boolean | `0` | Uses C++20 [char8_t]-based strings as the toml string data type. **_Experimental!_** |
| `TOML_CONFIG_HEADER` | string literal | undefined | Includes the given header file before the rest of the library. |
| `TOML_LARGE_FILES` | boolean | `0` | Uses 32-bit integers for line and column indices (instead of 16-bit). |
| `TOML_SMALL_FLOAT_TYPE` | type name | undefined | If your codebase has an additional 'small' float type (e.g. half-precision), this tells toml++ about it. |
Expand Down
3 changes: 3 additions & 0 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ PREDEFINED = TOML_DOXYGEN=1 \
TOML_ALWAYS_INLINE=inline \
TOML_MAY_THROW= \
TOML_NODISCARD_CTOR= \
TOML_ASYMMETRICAL_EQUALITY_OPS= \
TOML_START="namespace toml" \
TOML_END= \
__cpp_lib_char8_t=201811L
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = NO
Expand Down
7 changes: 3 additions & 4 deletions examples/parse_file.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <toml++/toml.h>
#include <iostream>
#include <fstream>
#include <toml++/toml.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
Expand All @@ -22,9 +22,8 @@ int main(int argc, char** argv)
}
try
{
const auto table = toml::parse(file, std::move(path));

std::cout << table << std::endl;
const auto tbl = toml::parse(file, std::move(path));
std::cout << tbl << std::endl;
}
catch (const toml::parse_error& err)
{
Expand Down
2 changes: 1 addition & 1 deletion examples/toml_to_json_transcoder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <toml++/toml.h>
#include <iostream>
#include <fstream>
#include <toml++/toml.h>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
Expand Down
25 changes: 19 additions & 6 deletions include/toml++/toml.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

// macro hygiene
#if TOML_UNDEF_MACROS
#undef TOML_EXCEPTIONS
#undef TOML_USE_STREAMS_FOR_FLOATS
#undef TOML_GCC_ATTR
#undef TOML_PUSH_WARNINGS
Expand Down Expand Up @@ -54,6 +53,10 @@
#undef TOML_DOXYGEN
#undef TOML_RELOPS_REORDERING
#undef TOML_ASYMMETRICAL_EQUALITY_OPS
#undef TOML_START
#undef TOML_END
#undef TOML_IMPL_START
#undef TOML_IMPL_END
#endif

/// \mainpage toml++
Expand Down Expand Up @@ -126,7 +129,7 @@
///
/// \ecpp
///
/// When exceptions are disabled parsing methods return a toml::parse_error and it is up to the caller
/// When exceptions are disabled parsing methods return a toml::parse_result and it is up to the caller
/// to check if parsing has been successful by examining the return value:
/// \cpp
/// #include <iostream>
Expand All @@ -151,7 +154,11 @@
/// return 0;
/// }
/// \ecpp
/// \see toml::parse_file()
///
/// \see
/// - toml::parse_file()
/// - toml::parse_result
/// - toml::parse_error
///
///////////////////////////////////
///
Expand Down Expand Up @@ -189,7 +196,7 @@
/// name = "toml++"
/// version = "0.1.0"
/// \eout
/// \see toml::parse()
/// \see toml::parse()
///
///////////////////////////////////
///
Expand Down Expand Up @@ -252,7 +259,11 @@
/// 'dinosaurs':
/// \eout
///
/// \see toml::node, toml::node_view, toml::array, toml::table
/// \see
/// - toml::node
/// - toml::node_view
/// - toml::array
/// - toml::table
///
///////////////////////////////////
///
Expand Down Expand Up @@ -317,7 +328,9 @@
/// ]
/// }
/// \eout
/// \see toml::default_formatter, toml::json_formatter
/// \see
/// - toml::default_formatter
/// - toml::json_formatter
///
///////////////////////////////////////////////////////////////////////
///
Expand Down
6 changes: 4 additions & 2 deletions include/toml++/toml_array.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "toml_value.h"

namespace toml::impl
TOML_IMPL_START
{
template <bool is_const>
class array_iterator final
Expand Down Expand Up @@ -174,8 +174,9 @@ namespace toml::impl
}
}
}
TOML_IMPL_END

namespace toml
TOML_START
{
[[nodiscard]] bool operator == (const table& lhs, const table& rhs) noexcept;

Expand Down Expand Up @@ -945,3 +946,4 @@ namespace toml
friend inline std::basic_ostream<CHAR>& operator << (std::basic_ostream<CHAR>&, const array&) TOML_MAY_THROW;
};
}
TOML_END
23 changes: 19 additions & 4 deletions include/toml++/toml_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,17 @@
__VA_ARGS__ [[nodiscard]] friend bool operator != (RHS rhs, LHS lhs) noexcept { return !(lhs == rhs); }
#endif

#if !TOML_DOXYGEN
#if TOML_EXCEPTIONS
#define TOML_START namespace toml { inline namespace wex
#else
#define TOML_START namespace toml { inline namespace woex
#endif
#define TOML_END }
#endif
#define TOML_IMPL_START TOML_START { namespace impl
#define TOML_IMPL_END } TOML_END

#include "toml_version.h"

#define TOML_MAKE_VERSION(maj, min, rev) \
Expand Down Expand Up @@ -292,7 +303,9 @@ TOML_POP_WARNINGS
// clang-format on

/// \brief The root namespace for all toml++ functions and types.
namespace toml
namespace toml { }

TOML_START
{
using namespace std::string_literals;
using namespace std::string_view_literals;
Expand Down Expand Up @@ -621,9 +634,9 @@ namespace toml

TOML_POP_WARNINGS
}
TOML_END

/// \brief Internal implementation details. No user-serviceable parts within.
namespace toml::impl
TOML_IMPL_START
{
template <typename T>
using string_map = std::map<string, T, std::less<>>; //heterogeneous lookup
Expand Down Expand Up @@ -840,8 +853,9 @@ namespace toml::impl

#undef TOML_P2S_DECL
}
TOML_IMPL_END

namespace toml
TOML_START
{
/// \brief Metafunction for determining if a type is a toml::table.
template <typename T>
Expand Down Expand Up @@ -905,3 +919,4 @@ namespace toml
}
}
}
TOML_END
3 changes: 2 additions & 1 deletion include/toml++/toml_date_time.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "toml_common.h"

namespace toml
TOML_START
{
/// \brief A local date.
struct date final
Expand Down Expand Up @@ -301,3 +301,4 @@ namespace toml
}
};
}
TOML_END
6 changes: 4 additions & 2 deletions include/toml++/toml_default_formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "toml_array.h"
#include "toml_utf8.h"

namespace toml::impl
TOML_IMPL_START
{
TOML_PUSH_WARNINGS
TOML_DISABLE_ALL_WARNINGS
Expand Down Expand Up @@ -131,8 +131,9 @@ namespace toml::impl
return (default_formatter_inline_columns(node) + starting_column_bias) > 120_sz;
}
}
TOML_IMPL_END

namespace toml
TOML_START
{
/// \brief A wrapper for printing TOML objects out to a stream as formatted TOML.
///
Expand Down Expand Up @@ -494,3 +495,4 @@ namespace toml
return lhs << default_formatter<CHAR>{ rhs };
}
}
TOML_END
6 changes: 4 additions & 2 deletions include/toml++/toml_formatter.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "toml_print_to_stream.h"

namespace toml
TOML_START
{
/// \brief Format flags for modifying how TOML data is printed to streams.
enum class format_flags : uint8_t
Expand All @@ -18,8 +18,9 @@ namespace toml
return static_cast<format_flags>( impl::unbox_enum(lhs) | impl::unbox_enum(rhs) );
}
}
TOML_END

namespace toml::impl
TOML_IMPL_START
{
template <typename CHAR = char>
class formatter
Expand Down Expand Up @@ -142,3 +143,4 @@ namespace toml::impl
{}
};
}
TOML_IMPL_END
4 changes: 2 additions & 2 deletions include/toml++/toml_json_formatter.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "toml_formatter.h"

namespace toml
TOML_START
{
/// \brief A wrapper for printing TOML objects out to a stream as formatted JSON.
///
Expand Down Expand Up @@ -160,4 +160,4 @@ namespace toml
base::clear_naked_newline();
}
}

TOML_END
5 changes: 4 additions & 1 deletion include/toml++/toml_node.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "toml_common.h"

namespace toml
TOML_START
{
/// \brief A TOML node.
///
Expand Down Expand Up @@ -69,6 +69,8 @@ namespace toml
[[nodiscard]] virtual bool is_integer() const noexcept { return false; }
/// \brief Returns true if this node is an floating-point value.
[[nodiscard]] virtual bool is_floating_point() const noexcept { return false; }
/// \brief Returns true if this node is an integer or floating-point value.
[[nodiscard]] virtual bool is_number() const noexcept { return false; }
/// \brief Returns true if this node is a boolean value.
[[nodiscard]] virtual bool is_boolean() const noexcept { return false; }
/// \brief Returns true if this node is a local date value.
Expand Down Expand Up @@ -400,3 +402,4 @@ namespace toml
}
};
}
TOML_END
Loading

0 comments on commit 3d653de

Please sign in to comment.