diff --git a/src/auto_mem.hh b/src/auto_mem.hh index 8c50800e..a23d3b0e 100644 --- a/src/auto_mem.hh +++ b/src/auto_mem.hh @@ -53,9 +53,7 @@ public: : am_ptr(ptr), am_free_func(default_free) { }; - auto_mem(auto_mem &am) - : am_ptr(am.release()), am_free_func(am.am_free_func) - {}; + auto_mem(const auto_mem &am) = delete; template explicit auto_mem(F free_func) diff --git a/src/log_format.cc b/src/log_format.cc index e47346be..c601f058 100644 --- a/src/log_format.cc +++ b/src/log_format.cc @@ -33,6 +33,8 @@ #include #include +#include + #include "base/string_util.hh" #include "fmt/format.h" #include "yajlpp/yajlpp.hh" @@ -626,7 +628,7 @@ log_format::scan_result_t external_log_format::scan(logfile &lf, if (this->elf_type == ELF_TYPE_JSON) { yajlpp_parse_context &ypc = *(this->jlf_parse_context); logline ll(li.li_file_range.fr_offset, 0, 0, LEVEL_INFO); - yajl_handle handle = this->jlf_yajl_handle.in(); + yajl_handle handle = this->jlf_yajl_handle.get(); json_log_userdata jlu(sbr); if (!this->lf_specialized && dst.size() >= 3) { @@ -1198,7 +1200,7 @@ void external_log_format::get_subline(const logline &ll, shared_buffer_ref &sbr, if (this->jlf_cached_offset != ll.get_offset() || this->jlf_cached_full != full_message) { yajlpp_parse_context &ypc = *(this->jlf_parse_context); - yajl_handle handle = this->jlf_yajl_handle.in(); + yajl_handle handle = this->jlf_yajl_handle.get(); json_log_userdata jlu(sbr); this->jlf_share_manager.invalidate_refs(); @@ -1651,13 +1653,14 @@ void external_log_format::build(std::vector &errors) { ": structured logs cannot have regexes"); } if (this->elf_type == ELF_TYPE_JSON) { - this->jlf_parse_context.reset( - new yajlpp_parse_context(this->elf_name.to_string())); - this->jlf_yajl_handle.reset(yajl_alloc( - &this->jlf_parse_context->ypc_callbacks, - NULL, - this->jlf_parse_context.get())); - yajl_config(this->jlf_yajl_handle.in(), yajl_dont_validate_strings, + this->jlf_parse_context = std::make_shared( + this->elf_name.to_string()); + this->jlf_yajl_handle.reset( + yajl_alloc(&this->jlf_parse_context->ypc_callbacks, + nullptr, + this->jlf_parse_context.get()), + yajl_handle_deleter()); + yajl_config(this->jlf_yajl_handle.get(), yajl_dont_validate_strings, 1); } @@ -2198,11 +2201,12 @@ std::shared_ptr external_log_format::specialized(int fmt_lock) if (this->elf_type == ELF_TYPE_JSON) { this->jlf_parse_context = std::make_shared(this->elf_name.to_string()); - this->jlf_yajl_handle.reset(yajl_alloc( - &this->jlf_parse_context->ypc_callbacks, - nullptr, - this->jlf_parse_context.get())); - yajl_config(this->jlf_yajl_handle.in(), yajl_dont_validate_strings, 1); + this->jlf_yajl_handle.reset( + yajl_alloc(&this->jlf_parse_context->ypc_callbacks, + nullptr, + this->jlf_parse_context.get()), + yajl_handle_deleter()); + yajl_config(this->jlf_yajl_handle.get(), yajl_dont_validate_strings, 1); this->jlf_cached_line.reserve(16 * 1024); } diff --git a/src/log_format_ext.hh b/src/log_format_ext.hh index f6a0af0c..86dc5b25 100644 --- a/src/log_format_ext.hh +++ b/src/log_format_ext.hh @@ -103,6 +103,14 @@ public: std::shared_ptr lp_pcre; }; + struct yajl_handle_deleter { + void operator()(yajl_handle handle) const { + if (handle != nullptr) { + yajl_free(handle); + } + } + }; + external_log_format(const intern_string_t name) : elf_file_pattern(".*"), elf_column_count(0), @@ -116,7 +124,7 @@ public: elf_type(ELF_TYPE_TEXT), jlf_hide_extra(false), jlf_cached_offset(-1), - jlf_yajl_handle(yajl_free), + jlf_yajl_handle(nullptr, yajl_handle_deleter()), elf_name(name) { this->jlf_line_offsets.reserve(128); }; @@ -439,7 +447,7 @@ public: std::vector jlf_cached_line; string_attrs_t jlf_line_attrs; std::shared_ptr jlf_parse_context; - auto_mem jlf_yajl_handle; + std::shared_ptr jlf_yajl_handle; private: const intern_string_t elf_name; diff --git a/src/mapbox/variant.hpp b/src/mapbox/variant.hpp index d7db91ae..06a46abe 100644 --- a/src/mapbox/variant.hpp +++ b/src/mapbox/variant.hpp @@ -75,16 +75,6 @@ public: }; // class bad_variant_access -template -struct MAPBOX_VARIANT_DEPRECATED static_visitor -{ - using result_type = R; - -protected: - static_visitor() {} - ~static_visitor() {} -}; - #if !defined(MAPBOX_VARIANT_MINIMIZE_SIZE) using type_index_t = unsigned int; #else @@ -170,44 +160,68 @@ template struct value_traits { using value_type = typename std::remove_const::type>::type; + using value_type_wrapper = recursive_wrapper; static constexpr type_index_t direct_index = direct_type::index; static constexpr bool is_direct = direct_index != invalid_value; - static constexpr type_index_t index = is_direct ? direct_index : convertible_type::index; + static constexpr type_index_t index_direct_or_wrapper = is_direct ? direct_index : direct_type::index; + static constexpr bool is_direct_or_wrapper = index_direct_or_wrapper != invalid_value; + static constexpr type_index_t index = is_direct_or_wrapper ? index_direct_or_wrapper : convertible_type::index; static constexpr bool is_valid = index != invalid_value; static constexpr type_index_t tindex = is_valid ? sizeof...(Types)-index : 0; using target_type = typename std::tuple_element>::type; }; -template -struct enable_if_type +template +struct copy_cvref { - using type = R; + using type = Dest; }; -template -struct result_of_unary_visit +template +struct copy_cvref { - using type = typename std::result_of::type; + using type = Dest const&; }; -template -struct result_of_unary_visit::type> +template +struct copy_cvref { - using type = typename F::result_type; + using type = Dest&; }; -template -struct result_of_binary_visit +template +struct copy_cvref { - using type = typename std::result_of::type; + using type = Dest&&; }; -template -struct result_of_binary_visit::type> +template +struct deduced_result_type +{}; + +template +struct deduced_result_type()(std::declval()...))> { - using type = typename F::result_type; + using type = decltype(std::declval()(std::declval()...)); }; +template +struct visitor_result_type : deduced_result_type +{}; + +// specialization for explicit result_type member in visitor class +template +struct visitor_result_type::type::result_type>())> +{ + using type = typename std::decay::type::result_type; +}; + +template +using result_of_unary_visit = typename visitor_result_type::type; + +template +using result_of_binary_visit = typename visitor_result_type::type; + template struct static_max; @@ -277,245 +291,174 @@ struct variant_helper<> template struct unwrapper { - static T const& apply_const(T const& obj) { return obj; } - static T& apply(T& obj) { return obj; } -}; + using value_type = T; -template -struct unwrapper> -{ - static auto apply_const(recursive_wrapper const& obj) - -> typename recursive_wrapper::type const& + template + static auto apply(typename std::remove_reference::type& var) + -> typename std::enable_if::value, + decltype(var.template get_unchecked())>::type { - return obj.get(); + return var.template get_unchecked(); } - static auto apply(recursive_wrapper& obj) - -> typename recursive_wrapper::type& + + template + static auto apply(typename std::remove_reference::type& var) + -> typename std::enable_if::value, + decltype(std::move(var.template get_unchecked()))>::type { - return obj.get(); + return std::move(var.template get_unchecked()); } }; template -struct unwrapper> -{ - static auto apply_const(std::reference_wrapper const& obj) - -> typename std::reference_wrapper::type const& - { - return obj.get(); - } - static auto apply(std::reference_wrapper& obj) - -> typename std::reference_wrapper::type& - { - return obj.get(); - } -}; +struct unwrapper> : unwrapper +{}; -template +template +struct unwrapper> : unwrapper +{}; + +template struct dispatcher; -template -struct dispatcher +template +struct dispatcher { - VARIANT_INLINE static R apply_const(V const& v, F&& f) + template + VARIANT_INLINE static R apply(V&& v, F&& f) { if (v.template is()) { - return f(unwrapper::apply_const(v.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(v)); } else { - return dispatcher::apply_const(v, std::forward(f)); - } - } - - VARIANT_INLINE static R apply(V& v, F&& f) - { - if (v.template is()) - { - return f(unwrapper::apply(v.template get_unchecked())); - } - else - { - return dispatcher::apply(v, std::forward(f)); + return dispatcher::apply(std::forward(v), std::forward(f)); } } }; -template -struct dispatcher +template +struct dispatcher { - VARIANT_INLINE static R apply_const(V const& v, F&& f) + template + VARIANT_INLINE static R apply(V&& v, F&& f) { - return f(unwrapper::apply_const(v.template get_unchecked())); - } - - VARIANT_INLINE static R apply(V& v, F&& f) - { - return f(unwrapper::apply(v.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(v)); } }; -template +template struct binary_dispatcher_rhs; -template -struct binary_dispatcher_rhs +template +struct binary_dispatcher_rhs { - VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f) + template + VARIANT_INLINE static R apply(V&& lhs, V&& rhs, F&& f) { if (rhs.template is()) // call binary functor { - return f(unwrapper::apply_const(lhs.template get_unchecked()), - unwrapper::apply_const(rhs.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(lhs), + unwrapper::template apply(rhs)); } else { - return binary_dispatcher_rhs::apply_const(lhs, rhs, std::forward(f)); - } - } - - VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f) - { - if (rhs.template is()) // call binary functor - { - return f(unwrapper::apply(lhs.template get_unchecked()), - unwrapper::apply(rhs.template get_unchecked())); - } - else - { - return binary_dispatcher_rhs::apply(lhs, rhs, std::forward(f)); + return binary_dispatcher_rhs::apply(std::forward(lhs), + std::forward(rhs), + std::forward(f)); } } }; -template -struct binary_dispatcher_rhs +template +struct binary_dispatcher_rhs { - VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f) + template + VARIANT_INLINE static R apply(V&& lhs, V&& rhs, F&& f) { - return f(unwrapper::apply_const(lhs.template get_unchecked()), - unwrapper::apply_const(rhs.template get_unchecked())); - } - - VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f) - { - return f(unwrapper::apply(lhs.template get_unchecked()), - unwrapper::apply(rhs.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(lhs), + unwrapper::template apply(rhs)); } }; -template +template struct binary_dispatcher_lhs; -template -struct binary_dispatcher_lhs +template +struct binary_dispatcher_lhs { - VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f) + template + VARIANT_INLINE static R apply(V&& lhs, V&& rhs, F&& f) { if (lhs.template is()) // call binary functor { - return f(unwrapper::apply_const(lhs.template get_unchecked()), - unwrapper::apply_const(rhs.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(lhs), + unwrapper::template apply(rhs)); } else { - return binary_dispatcher_lhs::apply_const(lhs, rhs, std::forward(f)); - } - } - - VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f) - { - if (lhs.template is()) // call binary functor - { - return f(unwrapper::apply(lhs.template get_unchecked()), - unwrapper::apply(rhs.template get_unchecked())); - } - else - { - return binary_dispatcher_lhs::apply(lhs, rhs, std::forward(f)); + return binary_dispatcher_lhs::apply(std::forward(lhs), + std::forward(rhs), + std::forward(f)); } } }; -template -struct binary_dispatcher_lhs +template +struct binary_dispatcher_lhs { - VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f) + template + VARIANT_INLINE static R apply(V&& lhs, V&& rhs, F&& f) { - return f(unwrapper::apply_const(lhs.template get_unchecked()), - unwrapper::apply_const(rhs.template get_unchecked())); - } - - VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f) - { - return f(unwrapper::apply(lhs.template get_unchecked()), - unwrapper::apply(rhs.template get_unchecked())); + return std::forward(f)(unwrapper::template apply(lhs), + unwrapper::template apply(rhs)); } }; -template +template struct binary_dispatcher; -template -struct binary_dispatcher +template +struct binary_dispatcher { - VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f) + template + VARIANT_INLINE static R apply(V&& v0, V&& v1, F&& f) { if (v0.template is()) { if (v1.template is()) { - return f(unwrapper::apply_const(v0.template get_unchecked()), - unwrapper::apply_const(v1.template get_unchecked())); // call binary functor + return std::forward(f)(unwrapper::template apply(v0), + unwrapper::template apply(v1)); // call binary functor } else { - return binary_dispatcher_rhs::apply_const(v0, v1, std::forward(f)); + return binary_dispatcher_rhs::apply(std::forward(v0), + std::forward(v1), + std::forward(f)); } } else if (v1.template is()) { - return binary_dispatcher_lhs::apply_const(v0, v1, std::forward(f)); + return binary_dispatcher_lhs::apply(std::forward(v0), + std::forward(v1), + std::forward(f)); } - return binary_dispatcher::apply_const(v0, v1, std::forward(f)); - } - - VARIANT_INLINE static R apply(V& v0, V& v1, F&& f) - { - if (v0.template is()) - { - if (v1.template is()) - { - return f(unwrapper::apply(v0.template get_unchecked()), - unwrapper::apply(v1.template get_unchecked())); // call binary functor - } - else - { - return binary_dispatcher_rhs::apply(v0, v1, std::forward(f)); - } - } - else if (v1.template is()) - { - return binary_dispatcher_lhs::apply(v0, v1, std::forward(f)); - } - return binary_dispatcher::apply(v0, v1, std::forward(f)); + return binary_dispatcher::apply(std::forward(v0), + std::forward(v1), + std::forward(f)); } }; -template -struct binary_dispatcher +template +struct binary_dispatcher { - VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f) + template + VARIANT_INLINE static R apply(V&& v0, V&& v1, F&& f) { - return f(unwrapper::apply_const(v0.template get_unchecked()), - unwrapper::apply_const(v1.template get_unchecked())); // call binary functor - } - - VARIANT_INLINE static R apply(V& v0, V& v1, F&& f) - { - return f(unwrapper::apply(v0.template get_unchecked()), - unwrapper::apply(v1.template get_unchecked())); // call binary functor + return std::forward(f)(unwrapper::template apply(v0), + unwrapper::template apply(v1)); // call binary functor } }; @@ -586,11 +529,19 @@ public: using types = std::tuple; private: using first_type = typename std::tuple_element<0, types>::type; + using unwrap_first_type = typename detail::unwrapper::value_type; using data_type = typename std::aligned_storage::type; using helper_type = detail::variant_helper; + template + using alternative_ref = typename detail::copy_cvref::type; + type_index_t type_index; +#ifdef __clang_analyzer__ + data_type data {}; +#else data_type data; +#endif public: VARIANT_INLINE variant() noexcept(std::is_nothrow_default_constructible::value) @@ -644,21 +595,34 @@ private: public: VARIANT_INLINE variant& operator=(variant&& other) + // note we check for nothrow-constructible, not nothrow-assignable, since + // move_assign uses move-construction via placement new. + noexcept(detail::conjunction...>::value) { + if (this == &other) { // playing safe in release mode, hit assertion in debug. + assert(false); + return *this; + } move_assign(std::move(other)); return *this; } VARIANT_INLINE variant& operator=(variant const& other) { - copy_assign(other); + if (this != &other) + copy_assign(other); return *this; } // conversions // move-assign - template - VARIANT_INLINE variant& operator=(T&& rhs) noexcept + template , + typename Enable = typename std::enable_if, typename Traits::value_type>::value>::type > + VARIANT_INLINE variant& operator=(T&& rhs) + // not that we check is_nothrow_constructible, not is_nothrow_move_assignable, + // since we construct a temporary + noexcept(std::is_nothrow_constructible::value + && std::is_nothrow_move_assignable>::value) { variant temp(std::forward(rhs)); move_assign(std::move(temp)); @@ -855,7 +819,7 @@ public: VARIANT_INLINE int which() const noexcept { - return static_cast(sizeof...(Types)-type_index - 1); + return static_cast(sizeof...(Types) - type_index - 1); } template ::type> - auto VARIANT_INLINE static visit(V const& v, F&& f) - -> decltype(detail::dispatcher::apply_const(v, std::forward(f))) + template , + typename R = detail::result_of_unary_visit> + VARIANT_INLINE static R visit(V&& v, F&& f) { - return detail::dispatcher::apply_const(v, std::forward(f)); - } - // non-const - template ::type> - auto VARIANT_INLINE static visit(V& v, F&& f) - -> decltype(detail::dispatcher::apply(v, std::forward(f))) - { - return detail::dispatcher::apply(v, std::forward(f)); + return detail::dispatcher::apply(std::forward(v), std::forward(f)); } // binary - // const - template ::type> - auto VARIANT_INLINE static binary_visit(V const& v0, V const& v1, F&& f) - -> decltype(detail::binary_dispatcher::apply_const(v0, v1, std::forward(f))) + template , + typename R = detail::result_of_binary_visit> + VARIANT_INLINE static R binary_visit(V&& v0, V&& v1, F&& f) { - return detail::binary_dispatcher::apply_const(v0, v1, std::forward(f)); - } - // non-const - template ::type> - auto VARIANT_INLINE static binary_visit(V& v0, V& v1, F&& f) - -> decltype(detail::binary_dispatcher::apply(v0, v1, std::forward(f))) - { - return detail::binary_dispatcher::apply(v0, v1, std::forward(f)); + return detail::binary_dispatcher::apply(std::forward(v0), + std::forward(v1), + std::forward(f)); } // match // unary template - auto VARIANT_INLINE match(Fs&&... fs) const + auto VARIANT_INLINE match(Fs&&... fs) const& -> decltype(variant::visit(*this, ::mapbox::util::make_visitor(std::forward(fs)...))) { return variant::visit(*this, ::mapbox::util::make_visitor(std::forward(fs)...)); } // non-const template - auto VARIANT_INLINE match(Fs&&... fs) + auto VARIANT_INLINE match(Fs&&... fs) & -> decltype(variant::visit(*this, ::mapbox::util::make_visitor(std::forward(fs)...))) { return variant::visit(*this, ::mapbox::util::make_visitor(std::forward(fs)...)); } + template + auto VARIANT_INLINE match(Fs&&... fs) && + -> decltype(variant::visit(std::move(*this), ::mapbox::util::make_visitor(std::forward(fs)...))) + { + return variant::visit(std::move(*this), ::mapbox::util::make_visitor(std::forward(fs)...)); + } ~variant() noexcept // no-throw destructor { @@ -962,33 +919,19 @@ public: }; // unary visitor interface -// const template -auto VARIANT_INLINE apply_visitor(F&& f, V const& v) -> decltype(V::visit(v, std::forward(f))) +auto VARIANT_INLINE apply_visitor(F&& f, V&& v) + -> decltype(v.visit(std::forward(v), std::forward(f))) { - return V::visit(v, std::forward(f)); -} - -// non-const -template -auto VARIANT_INLINE apply_visitor(F&& f, V& v) -> decltype(V::visit(v, std::forward(f))) -{ - return V::visit(v, std::forward(f)); + return v.visit(std::forward(v), std::forward(f)); } // binary visitor interface -// const template -auto VARIANT_INLINE apply_visitor(F&& f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, std::forward(f))) +auto VARIANT_INLINE apply_visitor(F&& f, V&& v0, V&& v1) + -> decltype(v0.binary_visit(std::forward(v0), std::forward(v1), std::forward(f))) { - return V::binary_visit(v0, v1, std::forward(f)); -} - -// non-const -template -auto VARIANT_INLINE apply_visitor(F&& f, V& v0, V& v1) -> decltype(V::binary_visit(v0, v1, std::forward(f))) -{ - return V::binary_visit(v0, v1, std::forward(f)); + return v0.binary_visit(std::forward(v0), std::forward(v1), std::forward(f)); } // getter interface @@ -1020,6 +963,78 @@ ResultType const& get_unchecked(T const& var) { return var.template get_unchecked(); } +// variant_size +template +struct variant_size; + +//variable templates is c++14 +//template +//constexpr std::size_t variant_size_v = variant_size::value; + +template +struct variant_size + : variant_size {}; + +template +struct variant_size + : variant_size {}; + +template +struct variant_size + : variant_size {}; + +template +struct variant_size> + : std::integral_constant {}; + +// variant_alternative +template +struct variant_alternative; + +#if defined(__clang__) +#if __has_builtin(__type_pack_element) +#define has_type_pack_element +#endif +#endif + +#if defined(has_type_pack_element) +template +struct variant_alternative> +{ + static_assert(sizeof...(Types) > Index , "Index out of range"); + using type = __type_pack_element; +}; +#else +template +struct variant_alternative> + : variant_alternative> +{ + static_assert(sizeof...(Types) > Index -1 , "Index out of range"); +}; + +template +struct variant_alternative<0, variant> +{ + using type = First; +}; + +#endif + +template +using variant_alternative_t = typename variant_alternative::type; + +template +struct variant_alternative + : std::add_const> {}; + +template +struct variant_alternative + : std::add_volatile> {}; + +template +struct variant_alternative + : std::add_cv> {}; + } // namespace util } // namespace mapbox @@ -1032,6 +1047,7 @@ struct hash< ::mapbox::util::variant> { return ::mapbox::util::apply_visitor(::mapbox::util::detail::hasher{}, v); } }; + } #endif // MAPBOX_UTIL_VARIANT_HPP diff --git a/src/mapbox/variant_cast.hpp b/src/mapbox/variant_cast.hpp new file mode 100644 index 00000000..fe1ab354 --- /dev/null +++ b/src/mapbox/variant_cast.hpp @@ -0,0 +1,85 @@ +#ifndef VARIANT_CAST_HPP +#define VARIANT_CAST_HPP + +#include + +namespace mapbox { +namespace util { + +namespace detail { + +template +class static_caster +{ +public: + template + T& operator()(V& v) const + { + return static_cast(v); + } +}; + +template +class dynamic_caster +{ +public: + using result_type = T&; + template + T& operator()(V& v, typename std::enable_if::value>::type* = nullptr) const + { + throw std::bad_cast(); + } + template + T& operator()(V& v, typename std::enable_if::value>::type* = nullptr) const + { + return dynamic_cast(v); + } +}; + +template +class dynamic_caster +{ +public: + using result_type = T*; + template + T* operator()(V& v, typename std::enable_if::value>::type* = nullptr) const + { + return nullptr; + } + template + T* operator()(V& v, typename std::enable_if::value>::type* = nullptr) const + { + return dynamic_cast(&v); + } +}; +} + +template +typename detail::dynamic_caster::result_type +dynamic_variant_cast(V& v) +{ + return mapbox::util::apply_visitor(detail::dynamic_caster(), v); +} + +template +typename detail::dynamic_caster::result_type +dynamic_variant_cast(const V& v) +{ + return mapbox::util::apply_visitor(detail::dynamic_caster(), v); +} + +template +T& static_variant_cast(V& v) +{ + return mapbox::util::apply_visitor(detail::static_caster(), v); +} + +template +const T& static_variant_cast(const V& v) +{ + return mapbox::util::apply_visitor(detail::static_caster(), v); +} +} +} + +#endif // VARIANT_CAST_HPP diff --git a/src/mapbox/variant_visitor.hpp b/src/mapbox/variant_visitor.hpp index 481eb652..54ddba0e 100644 --- a/src/mapbox/variant_visitor.hpp +++ b/src/mapbox/variant_visitor.hpp @@ -1,6 +1,8 @@ #ifndef MAPBOX_UTIL_VARIANT_VISITOR_HPP #define MAPBOX_UTIL_VARIANT_VISITOR_HPP +#include + namespace mapbox { namespace util { @@ -10,28 +12,31 @@ struct visitor; template struct visitor : Fn { - using type = Fn; using Fn::operator(); - visitor(Fn fn) : Fn(fn) {} + template + visitor(T&& fn) : Fn(std::forward(fn)) {} }; template struct visitor : Fn, visitor { - using type = visitor; using Fn::operator(); using visitor::operator(); - visitor(Fn fn, Fns... fns) : Fn(fn), visitor(fns...) {} + template + visitor(T&& fn, Ts&&... fns) + : Fn(std::forward(fn)) + , visitor(std::forward(fns)...) {} }; template -visitor make_visitor(Fns... fns) +visitor::type...> make_visitor(Fns&&... fns) { - return visitor(fns...); + return visitor::type...> + (std::forward(fns)...); } - + } // namespace util } // namespace mapbox diff --git a/src/views_vtab.cc b/src/views_vtab.cc index 30de0876..aa4cd3c2 100644 --- a/src/views_vtab.cc +++ b/src/views_vtab.cc @@ -80,11 +80,11 @@ struct from_sqlite { }; template<> -struct from_sqlite> { - inline pairoperator()(int argc, sqlite3_value **val, int argi) { +struct from_sqlite>> { + inline pair> operator()(int argc, sqlite3_value **val, int argi) { const char *pattern = (const char *) sqlite3_value_text(val[argi]); const char *errptr; - pcre *code; + auto_mem code; int eoff; if (pattern == nullptr || pattern[0] == '\0') { @@ -101,7 +101,7 @@ struct from_sqlite> { throw from_sqlite_conversion_error(errptr, argi); } - return make_pair(string(pattern), code); + return make_pair(string(pattern), std::move(code)); } }; @@ -458,7 +458,7 @@ CREATE TABLE lnav_view_filters ( nonstd::optional _filter_id, nonstd::optional enabled, nonstd::optional type, - pair pattern) { + pair> pattern) { textview_curses &tc = lnav_data.ld_views[view_index]; text_sub_source *tss = tc.get_sub_source(); filter_stack &fs = tss->get_filters(); @@ -470,7 +470,7 @@ CREATE TABLE lnav_view_filters ( type.value_or(text_filter::type_t::EXCLUDE), pattern.first, *filter_index, - pattern.second); + pattern.second.release()); fs.add_filter(pf); if (!enabled.value_or(true)) { pf->disable(); @@ -506,7 +506,7 @@ CREATE TABLE lnav_view_filters ( int64_t new_filter_id, bool enabled, text_filter::type_t type, - pair pattern) { + pair> pattern) { auto view_index = lnav_view_t(rowid >> 32); int filter_index = rowid & 0xffffffffLL; textview_curses &tc = lnav_data.ld_views[view_index]; @@ -533,7 +533,7 @@ CREATE TABLE lnav_view_filters ( auto pf = make_shared(type, pattern.first, tf->get_index(), - pattern.second); + pattern.second.release()); if (!enabled) { pf->disable(); diff --git a/src/vtab_module.hh b/src/vtab_module.hh index 8e234c60..90b0a542 100644 --- a/src/vtab_module.hh +++ b/src/vtab_module.hh @@ -222,7 +222,7 @@ struct ToSqliteVisitor { }; template - void operator()(T t) const { + void operator()(T&& t) const { to_sqlite(this->tsv_context, t); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2d4d614a..06443b77 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,6 +30,10 @@ add_executable(test_reltime test_reltime.cc) target_link_libraries(test_reltime diag PkgConfig::libpcre) add_test(NAME test_reltime COMMAND test_reltime) +add_executable(test_auto_mem test_auto_mem.cc) +target_link_libraries(test_auto_mem diag PkgConfig::libpcre) +add_test(NAME test_auto_mem COMMAND test_auto_mem) + add_executable(test_date_time_scanner test_date_time_scanner.cc) target_link_libraries(test_date_time_scanner diag PkgConfig::libpcre) add_test(NAME test_date_time_scanner COMMAND test_date_time_scanner) diff --git a/test/test_auto_mem.cc b/test/test_auto_mem.cc index deab1e65..c7b35403 100644 --- a/test/test_auto_mem.cc +++ b/test/test_auto_mem.cc @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) assert(md1.in() == &md1_val); { - auto_mem md_cp(md1); + auto_mem md_cp(std::move(md1)); assert(md1 == NULL); assert(free_count == 2);