Browse Source

Merge pull request #9917 from neheb/msm3

libmstch: Remove boost dependency
lilik-openwrt-22.03
Rosen Penev 5 years ago
committed by GitHub
parent
commit
1e57e6df7c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 608 additions and 3 deletions
  1. +2
    -3
      libs/libmstch/Makefile
  2. +138
    -0
      libs/libmstch/patches/010-wrench-fix-build-in-c-17-on-GCC-libstdc-and-on-clang.patch
  3. +442
    -0
      libs/libmstch/patches/020-switch-boost-variant-to-std-variant-and-to-C-17.patch
  4. +26
    -0
      libs/libmstch/patches/030-Fix-assignment-of-string-literals-to-node-conversion.patch

+ 2
- 3
libs/libmstch/Makefile View File

@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=libmstch
PKG_VERSION:=1.0.2
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/no1msd/mstch/tar.gz/$(PKG_VERSION)?
@ -14,7 +14,6 @@ PKG_MAINTAINER:=Amol Bhave <ambhave@fb.com>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
HOST_BUILD_DEPENDS:=boost/host
PKG_BUILD_PARALLEL:=1
CMAKE_INSTALL:=1
@ -26,7 +25,7 @@ define Package/libmstch
SECTION:=libs
CATEGORY:=Libraries
TITLE:=Complete implementation of {{mustache}} templates using modern C++
DEPENDS:=+boost +boost-container
DEPENDS:=+libstdcpp
URL:=https://github.com/no1msd/mstch
endef


+ 138
- 0
libs/libmstch/patches/010-wrench-fix-build-in-c-17-on-GCC-libstdc-and-on-clang.patch View File

@ -0,0 +1,138 @@
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

+ 442
- 0
libs/libmstch/patches/020-switch-boost-variant-to-std-variant-and-to-C-17.patch View File

@ -0,0 +1,442 @@
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

+ 26
- 0
libs/libmstch/patches/030-Fix-assignment-of-string-literals-to-node-conversion.patch View File

@ -0,0 +1,26 @@
From 6dd1986dc8b713c212def7f8eab7f38e705f17a5 Mon Sep 17 00:00:00 2001
From: Kira Backes <home_kira@kira-game.home.kirab.de>
Date: Wed, 6 Feb 2019 16:56:47 +0100
Subject: [PATCH] Fix assignment of string literals to node (conversion to
bool)
---
include/mstch/mstch.hpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/mstch/mstch.hpp b/include/mstch/mstch.hpp
index 2ea9855..bb86e78 100644
--- a/include/mstch/mstch.hpp
+++ b/include/mstch/mstch.hpp
@@ -118,6 +118,8 @@ struct node : std::variant<
node() : base_type(std::in_place_type<std::monostate>) {}
explicit node(const char* value) : base_type(std::in_place_type<std::string>, value) {}
+
+ node& operator=(const char* value) { return *this = std::string{value}; }
base_type& base() { return *this; }
base_type const& base() const { return *this; }
--
2.17.1

Loading…
Cancel
Save