#ifndef BOOST_LEAF_DETAIL_ENCODER_HPP_INCLUDED #define BOOST_LEAF_DETAIL_ENCODER_HPP_INCLUDED // Copyright 2018-2026 Emil Dotchevski and Reverge Studios, Inc. // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include namespace boost { namespace leaf { namespace serialization { struct encoder_adl {}; template typename std::enable_if< sizeof(T) == sizeof(decltype(std::declval().value)), decltype(output(std::declval(), std::declval().value), void())>::type output(Encoder & e, T const & x) { output(e, x.value); } } namespace detail { class encoder: serialization::encoder_adl { encoder(encoder const &) = delete; encoder & operator=(encoder const &) = delete; type_name const type_; void * const e_; bool dispatch_() { return false; } template bool dispatch_(F1 && f1, Fn && ... fn) { using encoder_type = typename std::decay>::type; if (encoder_type * e = get()) { std::forward(f1)(*e); return true; } return dispatch_(std::forward(fn)...); } protected: template explicit encoder(Encoder * e) noexcept: type_(get_type_name()), e_(e) { } public: template Encoder * get() noexcept { return type_ == get_type_name() ? static_cast(e_) : nullptr; } template bool dispatch(Fn && ... fn) { using encoder_types = leaf_detail_mp11::mp_list>::type...>; static_assert(std::is_same>::value, "Duplicate encoder types in dispatch"); return dispatch_(std::forward(fn)...); } }; template struct encoder_adaptor: encoder { explicit encoder_adaptor(Encoder & e) noexcept: encoder(&e) { } }; } // namespace detail } } // namespace boost::leaf #endif // #ifndef BOOST_LEAF_DETAIL_ENCODER_HPP_INCLUDED