+++ /dev/null
-From ee63b2717de7261c95733bc1742d8dfc3317429e Mon Sep 17 00:00:00 2001
-From: "Damien Buhl (alias daminetreg)" <damien.buhl@lecbna.org>
-Date: Thu, 6 Sep 2018 05:07:03 +0200
-Subject: [PATCH] :wrench: fix build in c++17 on GCC libstdc++ and on
- clang+libc++.
-
----
- CMakeLists.txt | 3 +--
- include/mstch/mstch.hpp | 4 ++--
- src/render_context.cpp | 4 ++--
- src/state/in_section.cpp | 6 +++---
- src/state/outside_section.cpp | 4 ++--
- src/visitor/render_node.hpp | 2 +-
- src/visitor/render_section.hpp | 4 ++--
- 7 files changed, 13 insertions(+), 14 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 8d8e0c7..7ee9f01 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -6,12 +6,11 @@ option(WITH_BENCHMARK "enable building benchmark executable" OFF)
-
- set(CMAKE_INCLUDE_CURRENT_DIR ON)
- set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
--set(CMAKE_BUILD_TYPE Release)
-
- set(mstch_VERSION 1.0.1)
-
- if(NOT MSVC)
-- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -O3")
-+ add_compile_options(-Wall -Wextra)
- endif()
-
- add_subdirectory(src)
-diff --git a/include/mstch/mstch.hpp b/include/mstch/mstch.hpp
-index 58d3330..0af9e4d 100644
---- a/include/mstch/mstch.hpp
-+++ b/include/mstch/mstch.hpp
-@@ -97,11 +97,11 @@ using node = boost::make_recursive_variant<
- std::nullptr_t, std::string, int, double, bool,
- internal::lambda_t<boost::recursive_variant_>,
- std::shared_ptr<internal::object_t<boost::recursive_variant_>>,
-- std::map<const std::string, boost::recursive_variant_>,
-+ std::map<std::string, boost::recursive_variant_>,
- std::vector<boost::recursive_variant_>>::type;
- using object = internal::object_t<node>;
- using lambda = internal::lambda_t<node>;
--using map = std::map<const std::string, node>;
-+using map = std::map<std::string, node>;
- using array = std::vector<node>;
-
- std::string render(
-diff --git a/src/render_context.cpp b/src/render_context.cpp
-index 90b2ffc..756114d 100644
---- a/src/render_context.cpp
-+++ b/src/render_context.cpp
-@@ -41,8 +41,8 @@ const mstch::node& render_context::find_node(
- {&find_node(token.substr(0, token.rfind('.')), current_nodes)});
- else
- for (auto& node: current_nodes)
-- if (visit(has_token(token), *node))
-- return visit(get_token(token, *node), *node);
-+ if (mstch::visit(has_token(token), *node))
-+ return mstch::visit(get_token(token, *node), *node);
- return null_node;
- }
-
-diff --git a/src/state/in_section.cpp b/src/state/in_section.cpp
-index a139913..0062493 100644
---- a/src/state/in_section.cpp
-+++ b/src/state/in_section.cpp
-@@ -16,9 +16,9 @@ std::string in_section::render(render_context& ctx, const token& token) {
- auto& node = ctx.get_node(m_start_token.name());
- std::string out;
-
-- if (m_type == type::normal && !visit(is_node_empty(), node))
-- out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
-- else if (m_type == type::inverted && visit(is_node_empty(), node))
-+ if (m_type == type::normal && !mstch::visit(is_node_empty(), node))
-+ out = mstch::visit(render_section(ctx, m_section, m_start_token.delims()), node);
-+ else if (m_type == type::inverted && mstch::visit(is_node_empty(), node))
- out = render_context::push(ctx).render(m_section);
-
- ctx.set_state<outside_section>();
-diff --git a/src/state/outside_section.cpp b/src/state/outside_section.cpp
-index c9817b1..46e204b 100644
---- a/src/state/outside_section.cpp
-+++ b/src/state/outside_section.cpp
-@@ -18,9 +18,9 @@ std::string outside_section::render(
- ctx.set_state<in_section>(in_section::type::inverted, token);
- break;
- case token::type::variable:
-- return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
-+ return mstch::visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
- case token::type::unescaped_variable:
-- return visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
-+ return mstch::visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
- case token::type::text:
- return token.raw();
- case token::type::partial:
-diff --git a/src/visitor/render_node.hpp b/src/visitor/render_node.hpp
-index 633dd4d..d5d5b40 100644
---- a/src/visitor/render_node.hpp
-+++ b/src/visitor/render_node.hpp
-@@ -38,7 +38,7 @@ class render_node: public boost::static_visitor<std::string> {
-
- std::string operator()(const lambda& value) const {
- template_type interpreted{value([this](const mstch::node& n) {
-- return visit(render_node(m_ctx), n);
-+ return mstch::visit(render_node(m_ctx), n);
- })};
- auto rendered = render_context::push(m_ctx).render(interpreted);
- return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
-diff --git a/src/visitor/render_section.hpp b/src/visitor/render_section.hpp
-index f2d5259..ac753e3 100644
---- a/src/visitor/render_section.hpp
-+++ b/src/visitor/render_section.hpp
-@@ -31,7 +31,7 @@ class render_section: public boost::static_visitor<std::string> {
- for (auto& token: m_section)
- section_str += token.raw();
- template_type interpreted{fun([this](const mstch::node& n) {
-- return visit(render_node(m_ctx), n);
-+ return mstch::visit(render_node(m_ctx), n);
- }, section_str), m_delims};
- return render_context::push(m_ctx).render(interpreted);
- }
-@@ -42,7 +42,7 @@ class render_section: public boost::static_visitor<std::string> {
- return render_context::push(m_ctx, array).render(m_section);
- else
- for (auto& item: array)
-- out += visit(render_section(
-+ out += mstch::visit(render_section(
- m_ctx, m_section, m_delims, flag::keep_array), item);
- return out;
- }
---
-2.17.1
-
+++ /dev/null
-From 8e9679af05f0132e2934f8d7e1bfbaf36dc57cd7 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= <t.klatt.oss@mailbox.org>
-Date: Tue, 27 Nov 2018 20:56:02 +0100
-Subject: [PATCH] switch boost::variant to std::variant and to C++17
-
-This is based on work by @mbits-libs as published on Github:
-mbits-libs/libmstch@747c5eed3ddbff94a0354f1b1d217f547867ef27
-
-The `is_node_empty` type had to be extended to detect the std::variant's
-default type `std::monostate` as an empty value. This change made all
-the unit tests pass.
----
- CMakeLists.txt | 6 ++-
- include/mstch/mstch.hpp | 41 ++++++++++++++++----
- src/CMakeLists.txt | 6 +--
- src/utils.hpp | 13 ++++---
- src/visitor/get_token.hpp | 4 +-
- src/visitor/has_token.hpp | 4 +-
- src/visitor/is_node_empty.hpp | 16 +++++---
- src/visitor/render_node.hpp | 69 +++++++++++++++-------------------
- src/visitor/render_section.hpp | 48 ++++++++++++-----------
- test/CMakeLists.txt | 3 --
- test/test_main.cpp | 2 +-
- 11 files changed, 115 insertions(+), 97 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 7ee9f01..9df666f 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -7,10 +7,12 @@ option(WITH_BENCHMARK "enable building benchmark executable" OFF)
- set(CMAKE_INCLUDE_CURRENT_DIR ON)
- set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
-
--set(mstch_VERSION 1.0.1)
-+set(mstch_VERSION 1.0.2)
-
- if(NOT MSVC)
-- add_compile_options(-Wall -Wextra)
-+ add_compile_options(-std=c++17 -Wall -Wextra -O3)
-+else()
-+ add_compile_options(/std:c++latest)
- endif()
-
- add_subdirectory(src)
-diff --git a/include/mstch/mstch.hpp b/include/mstch/mstch.hpp
-index 0af9e4d..2ea9855 100644
---- a/include/mstch/mstch.hpp
-+++ b/include/mstch/mstch.hpp
-@@ -5,8 +5,7 @@
- #include <string>
- #include <memory>
- #include <functional>
--
--#include <boost/variant.hpp>
-+#include <variant>
-
- namespace mstch {
-
-@@ -93,12 +92,38 @@ class lambda_t {
-
- }
-
--using node = boost::make_recursive_variant<
-- std::nullptr_t, std::string, int, double, bool,
-- internal::lambda_t<boost::recursive_variant_>,
-- std::shared_ptr<internal::object_t<boost::recursive_variant_>>,
-- std::map<std::string, boost::recursive_variant_>,
-- std::vector<boost::recursive_variant_>>::type;
-+struct node : std::variant<
-+ std::monostate, std::nullptr_t, std::string, int, unsigned int, double, bool,
-+ internal::lambda_t<node>,
-+ std::shared_ptr<internal::object_t<node>>,
-+ std::map<const std::string, node>,
-+ std::vector<node>
-+> {
-+ using empty_type = std::monostate;
-+ using lambda_type = internal::lambda_t<node>;
-+ using shared_ptr_type = std::shared_ptr<internal::object_t<node>>;
-+ using map_type = std::map<const std::string, node>;
-+ using vector_type = std::vector<node>;
-+
-+ using base_type = std::variant<
-+ std::monostate, std::nullptr_t, std::string, int, unsigned int, double, bool,
-+ internal::lambda_t<node>,
-+ std::shared_ptr<internal::object_t<node>>,
-+ std::map<const std::string, node>,
-+ std::vector<node>
-+ >;
-+
-+ using base_type::base_type;
-+
-+ node() : base_type(std::in_place_type<std::monostate>) {}
-+
-+ explicit node(const char* value) : base_type(std::in_place_type<std::string>, value) {}
-+
-+ base_type& base() { return *this; }
-+ base_type const& base() const { return *this; }
-+};
-+
-+using empty = std::monostate;
- using object = internal::object_t<node>;
- using lambda = internal::lambda_t<node>;
- using map = std::map<std::string, node>;
-diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
-index 6517fc4..22d4f41 100644
---- a/src/CMakeLists.txt
-+++ b/src/CMakeLists.txt
-@@ -1,11 +1,8 @@
--find_package(Boost 1.54 REQUIRED)
--
- set(mstch_INCLUDE_DIR
- ${PROJECT_SOURCE_DIR}/include CACHE STRING "mstch include directory")
-
- include_directories(
-- ${mstch_INCLUDE_DIR}
-- ${Boost_INCLUDE_DIR})
-+ ${mstch_INCLUDE_DIR})
-
- set(SRC
- state/in_section.cpp
-@@ -62,3 +59,4 @@ install(FILES
- "${CMAKE_CURRENT_BINARY_DIR}/mstch/mstch-config-version.cmake"
- DESTINATION lib/cmake/mstch
- COMPONENT Devel)
-+
-diff --git a/src/utils.hpp b/src/utils.hpp
-index 9041a3e..ea19029 100644
---- a/src/utils.hpp
-+++ b/src/utils.hpp
-@@ -1,7 +1,8 @@
- #pragma once
-
- #include <string>
--#include <boost/variant/apply_visitor.hpp>
-+#include <vector>
-+#include <variant>
-
- namespace mstch {
-
-@@ -13,11 +14,13 @@ citer first_not_ws(criter begin, criter end);
- std::string html_escape(const std::string& str);
- criter reverse(citer it);
-
--template<class... Args>
--auto visit(Args&&... args) -> decltype(boost::apply_visitor(
-- std::forward<Args>(args)...))
-+template<class Visitor, class... Visited>
-+decltype(auto) visit(Visitor&& visitor, Visited&&... nodes)
- {
-- return boost::apply_visitor(std::forward<Args>(args)...);
-+ return std::visit(std::forward<Visitor>(visitor), nodes.base()...);
- }
-
-+template <typename T, typename U>
-+constexpr bool is_v = std::is_same_v<T, U>;
-+
- }
-diff --git a/src/visitor/get_token.hpp b/src/visitor/get_token.hpp
-index d41ab6e..f7b1714 100644
---- a/src/visitor/get_token.hpp
-+++ b/src/visitor/get_token.hpp
-@@ -1,13 +1,11 @@
- #pragma once
-
--#include <boost/variant/static_visitor.hpp>
--
- #include "mstch/mstch.hpp"
- #include "has_token.hpp"
-
- namespace mstch {
-
--class get_token: public boost::static_visitor<const mstch::node&> {
-+class get_token {
- public:
- get_token(const std::string& token, const mstch::node& node):
- m_token(token), m_node(node)
-diff --git a/src/visitor/has_token.hpp b/src/visitor/has_token.hpp
-index 5ab30d4..0076f97 100644
---- a/src/visitor/has_token.hpp
-+++ b/src/visitor/has_token.hpp
-@@ -1,12 +1,10 @@
- #pragma once
-
--#include <boost/variant/static_visitor.hpp>
--
- #include "mstch/mstch.hpp"
-
- namespace mstch {
-
--class has_token: public boost::static_visitor<bool> {
-+class has_token {
- public:
- has_token(const std::string& token): m_token(token) {
- }
-diff --git a/src/visitor/is_node_empty.hpp b/src/visitor/is_node_empty.hpp
-index a0ae432..d7434e7 100644
---- a/src/visitor/is_node_empty.hpp
-+++ b/src/visitor/is_node_empty.hpp
-@@ -1,18 +1,20 @@
- #pragma once
-
--#include <boost/variant/static_visitor.hpp>
--
- #include "mstch/mstch.hpp"
-
- namespace mstch {
-
--class is_node_empty: public boost::static_visitor<bool> {
-+class is_node_empty {
- public:
- template<class T>
- bool operator()(const T&) const {
- return false;
- }
-
-+ bool operator()(const empty&) const {
-+ return true;
-+ }
-+
- bool operator()(const std::nullptr_t&) const {
- return true;
- }
-@@ -21,6 +23,10 @@ class is_node_empty: public boost::static_visitor<bool> {
- return value == 0;
- }
-
-+ bool operator()(const unsigned int& value) const {
-+ return value == 0;
-+ }
-+
- bool operator()(const double& value) const {
- return value == 0;
- }
-@@ -30,11 +36,11 @@ class is_node_empty: public boost::static_visitor<bool> {
- }
-
- bool operator()(const std::string& value) const {
-- return value == "";
-+ return value.empty();
- }
-
- bool operator()(const array& array) const {
-- return array.size() == 0;
-+ return array.empty();
- }
- };
-
-diff --git a/src/visitor/render_node.hpp b/src/visitor/render_node.hpp
-index d5d5b40..d8f5315 100644
---- a/src/visitor/render_node.hpp
-+++ b/src/visitor/render_node.hpp
-@@ -1,7 +1,6 @@
- #pragma once
-
- #include <sstream>
--#include <boost/variant/static_visitor.hpp>
-
- #include "render_context.hpp"
- #include "mstch/mstch.hpp"
-@@ -9,47 +8,41 @@
-
- namespace mstch {
-
--class render_node: public boost::static_visitor<std::string> {
-- public:
-+class render_node {
-+public:
- enum class flag { none, escape_html };
-- render_node(render_context& ctx, flag p_flag = flag::none):
-- m_ctx(ctx), m_flag(p_flag)
-+ render_node(render_context& ctx, flag p_flag = flag::none) :
-+ m_ctx(ctx), m_flag(p_flag)
- {
- }
-
-- template<class T>
-- std::string operator()(const T&) const {
-- return "";
-- }
--
-- std::string operator()(const int& value) const {
-- return std::to_string(value);
-- }
--
-- std::string operator()(const double& value) const {
-- std::stringstream ss;
-- ss << value;
-- return ss.str();
-- }
--
-- std::string operator()(const bool& value) const {
-- return value ? "true" : "false";
-- }
--
-- std::string operator()(const lambda& value) const {
-- template_type interpreted{value([this](const mstch::node& n) {
-- return mstch::visit(render_node(m_ctx), n);
-- })};
-- auto rendered = render_context::push(m_ctx).render(interpreted);
-- return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
-- }
--
-- std::string operator()(const std::string& value) const {
-- return (m_flag == flag::escape_html) ? html_escape(value) : value;
-- }
--
-- private:
-- render_context& m_ctx;
-+ template <typename T>
-+ std::string operator()(const T& value) const {
-+ if constexpr(is_v<T, int>) {
-+ return std::to_string(value);
-+ } else if constexpr(is_v<T, unsigned int>) {
-+ return std::to_string(value);
-+ } else if constexpr(is_v<T, double>) {
-+ std::stringstream ss;
-+ ss << value;
-+ return ss.str();
-+ } else if constexpr(is_v<T, bool>) {
-+ return value ? "true" : "false";
-+ } else if constexpr(is_v<T, lambda>) {
-+ template_type interpreted{ value([this](const mstch::node& n) {
-+ return mstch::visit(render_node(m_ctx), n);
-+ }) };
-+ auto rendered = render_context::push(m_ctx).render(interpreted);
-+ return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
-+ } else if constexpr(is_v<T, std::string>) {
-+ return (m_flag == flag::escape_html) ? html_escape(value) : value;
-+ }
-+
-+ return {};
-+ };
-+
-+private:
-+ render_context & m_ctx;
- flag m_flag;
- };
-
-diff --git a/src/visitor/render_section.hpp b/src/visitor/render_section.hpp
-index ac753e3..0c08c17 100644
---- a/src/visitor/render_section.hpp
-+++ b/src/visitor/render_section.hpp
-@@ -1,7 +1,5 @@
- #pragma once
-
--#include <boost/variant/static_visitor.hpp>
--
- #include "render_context.hpp"
- #include "mstch/mstch.hpp"
- #include "utils.hpp"
-@@ -9,7 +7,7 @@
-
- namespace mstch {
-
--class render_section: public boost::static_visitor<std::string> {
-+class render_section {
- public:
- enum class flag { none, keep_array };
- render_section(
-@@ -22,29 +20,29 @@ class render_section: public boost::static_visitor<std::string> {
- }
-
- template<class T>
-- std::string operator()(const T& t) const {
-- return render_context::push(m_ctx, t).render(m_section);
-- }
--
-- std::string operator()(const lambda& fun) const {
-- std::string section_str;
-- for (auto& token: m_section)
-- section_str += token.raw();
-- template_type interpreted{fun([this](const mstch::node& n) {
-- return mstch::visit(render_node(m_ctx), n);
-- }, section_str), m_delims};
-- return render_context::push(m_ctx).render(interpreted);
-- }
--
-- std::string operator()(const array& array) const {
-- std::string out;
-- if (m_flag == flag::keep_array)
-- return render_context::push(m_ctx, array).render(m_section);
-- else
-- for (auto& item: array)
-- out += mstch::visit(render_section(
-+ std::string operator()(const T& value) const {
-+ if constexpr(is_v<T, lambda>) {
-+ std::string section_str;
-+ for (auto& token : m_section) {
-+ section_str += token.raw();
-+ }
-+ template_type interpreted{ value([this](const mstch::node& n) {
-+ return mstch::visit(render_node(m_ctx), n);
-+ }, section_str), m_delims };
-+ return render_context::push(m_ctx).render(interpreted);
-+ } else if constexpr(is_v<T, array>) {
-+ std::string out;
-+ if (m_flag == flag::keep_array) {
-+ return render_context::push(m_ctx, value).render(m_section);
-+ } else {
-+ for (auto& item: value) {
-+ out += mstch::visit(render_section(
- m_ctx, m_section, m_delims, flag::keep_array), item);
-- return out;
-+ }
-+ }
-+ return out;
-+ }
-+ return render_context::push(m_ctx, value).render(m_section);
- }
-
- private:
-diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
-index 061bc2e..b290b65 100644
---- a/test/CMakeLists.txt
-+++ b/test/CMakeLists.txt
-@@ -1,10 +1,7 @@
--find_package(Boost 1.54 REQUIRED)
--
- include_directories(
- ${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/vendor/Catch/single_include
- ${CMAKE_SOURCE_DIR}/vendor/rapidjson/include
-- ${Boost_INCLUDE_DIR})
-
- file(GLOB data_files RELATIVE
- "${CMAKE_SOURCE_DIR}/test/data"
-diff --git a/test/test_main.cpp b/test/test_main.cpp
-index a52fe3c..d823a24 100644
---- a/test/test_main.cpp
-+++ b/test/test_main.cpp
-@@ -65,7 +65,7 @@ mstch::node parse_with_rapidjson(const std::string& str) {
- }
-
- #define SPECS_TEST(x) TEST_CASE("specs_" #x) { \
-- using boost::get; \
-+ using std::get; \
- auto data = parse_with_rapidjson(x ## _json); \
- for (auto& test_item: get<mstch::array>(get<mstch::map>(data)["tests"])) {\
- auto test = get<mstch::map>(test_item); \
---
-2.17.1
-