From: Rosen Penev Date: Tue, 3 Sep 2019 23:10:22 +0000 (-0700) Subject: libmstch: Remove boost dependency X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=refs%2Fpull%2F9917%2Fhead;p=feed%2Fpackages.git libmstch: Remove boost dependency Added patches that convert Boost functionality to C++17. Signed-off-by: Rosen Penev --- diff --git a/libs/libmstch/Makefile b/libs/libmstch/Makefile index bff939a4e5..fe3e2ea29e 100644 --- a/libs/libmstch/Makefile +++ b/libs/libmstch/Makefile @@ -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 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 diff --git a/libs/libmstch/patches/010-wrench-fix-build-in-c-17-on-GCC-libstdc-and-on-clang.patch b/libs/libmstch/patches/010-wrench-fix-build-in-c-17-on-GCC-libstdc-and-on-clang.patch new file mode 100644 index 0000000000..0c96ec4f59 --- /dev/null +++ b/libs/libmstch/patches/010-wrench-fix-build-in-c-17-on-GCC-libstdc-and-on-clang.patch @@ -0,0 +1,138 @@ +From ee63b2717de7261c95733bc1742d8dfc3317429e Mon Sep 17 00:00:00 2001 +From: "Damien Buhl (alias daminetreg)" +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, + std::shared_ptr>, +- std::map, ++ std::map, + std::vector>::type; + using object = internal::object_t; + using lambda = internal::lambda_t; +-using map = std::map; ++using map = std::map; + using array = std::vector; + + 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(); +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::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 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 { + 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 { + 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 + diff --git a/libs/libmstch/patches/020-switch-boost-variant-to-std-variant-and-to-C-17.patch b/libs/libmstch/patches/020-switch-boost-variant-to-std-variant-and-to-C-17.patch new file mode 100644 index 0000000000..361318e8b2 --- /dev/null +++ b/libs/libmstch/patches/020-switch-boost-variant-to-std-variant-and-to-C-17.patch @@ -0,0 +1,442 @@ +From 8e9679af05f0132e2934f8d7e1bfbaf36dc57cd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Torbj=C3=B6rn=20Klatt?= +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 + #include + #include +- +-#include ++#include + + 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, +- std::shared_ptr>, +- std::map, +- std::vector>::type; ++struct node : std::variant< ++ std::monostate, std::nullptr_t, std::string, int, unsigned int, double, bool, ++ internal::lambda_t, ++ std::shared_ptr>, ++ std::map, ++ std::vector ++> { ++ using empty_type = std::monostate; ++ using lambda_type = internal::lambda_t; ++ using shared_ptr_type = std::shared_ptr>; ++ using map_type = std::map; ++ using vector_type = std::vector; ++ ++ using base_type = std::variant< ++ std::monostate, std::nullptr_t, std::string, int, unsigned int, double, bool, ++ internal::lambda_t, ++ std::shared_ptr>, ++ std::map, ++ std::vector ++ >; ++ ++ using base_type::base_type; ++ ++ node() : base_type(std::in_place_type) {} ++ ++ explicit node(const char* value) : base_type(std::in_place_type, value) {} ++ ++ base_type& base() { return *this; } ++ base_type const& base() const { return *this; } ++}; ++ ++using empty = std::monostate; + using object = internal::object_t; + using lambda = internal::lambda_t; + using map = std::map; +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 +-#include ++#include ++#include + + 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 +-auto visit(Args&&... args) -> decltype(boost::apply_visitor( +- std::forward(args)...)) ++template ++decltype(auto) visit(Visitor&& visitor, Visited&&... nodes) + { +- return boost::apply_visitor(std::forward(args)...); ++ return std::visit(std::forward(visitor), nodes.base()...); + } + ++template ++constexpr bool is_v = std::is_same_v; ++ + } +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 +- + #include "mstch/mstch.hpp" + #include "has_token.hpp" + + namespace mstch { + +-class get_token: public boost::static_visitor { ++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 +- + #include "mstch/mstch.hpp" + + namespace mstch { + +-class has_token: public boost::static_visitor { ++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 +- + #include "mstch/mstch.hpp" + + namespace mstch { + +-class is_node_empty: public boost::static_visitor { ++class is_node_empty { + public: + template + 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 { + 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 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 +-#include + + #include "render_context.hpp" + #include "mstch/mstch.hpp" +@@ -9,47 +8,41 @@ + + namespace mstch { + +-class render_node: public boost::static_visitor { +- 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 +- 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 ++ std::string operator()(const T& value) const { ++ if constexpr(is_v) { ++ return std::to_string(value); ++ } else if constexpr(is_v) { ++ return std::to_string(value); ++ } else if constexpr(is_v) { ++ std::stringstream ss; ++ ss << value; ++ return ss.str(); ++ } else if constexpr(is_v) { ++ return value ? "true" : "false"; ++ } else if constexpr(is_v) { ++ 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) { ++ 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 +- + #include "render_context.hpp" + #include "mstch/mstch.hpp" + #include "utils.hpp" +@@ -9,7 +7,7 @@ + + namespace mstch { + +-class render_section: public boost::static_visitor { ++class render_section { + public: + enum class flag { none, keep_array }; + render_section( +@@ -22,29 +20,29 @@ class render_section: public boost::static_visitor { + } + + template +- 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) { ++ 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) { ++ 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(get(data)["tests"])) {\ + auto test = get(test_item); \ +-- +2.17.1 + diff --git a/libs/libmstch/patches/030-Fix-assignment-of-string-literals-to-node-conversion.patch b/libs/libmstch/patches/030-Fix-assignment-of-string-literals-to-node-conversion.patch new file mode 100644 index 0000000000..72a33131bc --- /dev/null +++ b/libs/libmstch/patches/030-Fix-assignment-of-string-literals-to-node-conversion.patch @@ -0,0 +1,26 @@ +From 6dd1986dc8b713c212def7f8eab7f38e705f17a5 Mon Sep 17 00:00:00 2001 +From: Kira Backes +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) {} + + explicit node(const char* value) : base_type(std::in_place_type, 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 +