boost/json/detail/stack.hpp
// // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com) // // 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) // // Official repository: https://github.com/boostorg/json // #ifndef BOOST_JSON_DETAIL_STACK_HPP #define BOOST_JSON_DETAIL_STACK_HPP #include <boost/json/detail/config.hpp> #include <boost/json/storage_ptr.hpp> #include <boost/mp11/integral.hpp> #include <cstring> #include <type_traits> namespace boost { namespace json { namespace detail { #if defined( BOOST_LIBSTDCXX_VERSION ) && BOOST_LIBSTDCXX_VERSION < 50000 template<class T> struct is_trivially_copy_assignable : mp11::mp_bool< std::is_copy_assignable<T>::value && std::has_trivial_copy_assign<T>::value > {}; #else using std::is_trivially_copy_assignable; #endif class stack { template< class T = void > struct non_trivial; storage_ptr sp_; std::size_t cap_ = 0; std::size_t size_ = 0; non_trivial<>* head_ = nullptr; unsigned char* base_ = nullptr; unsigned char* buf_ = nullptr; public: BOOST_JSON_DECL ~stack(); stack() = default; stack( storage_ptr sp, unsigned char* buf, std::size_t buf_size) noexcept; bool empty() const noexcept { return size_ == 0; } BOOST_JSON_DECL void clear() noexcept; void reserve(std::size_t n) { if(n > cap_) reserve_impl(n); } template<class T> void push(T&& t) { using U = remove_cvref<T>; push( static_cast<T&&>(t), is_trivially_copy_assignable<U>() ); } template<class T> void push_unchecked( T const& t); template<class T> void peek(T& t); template<class T> void pop(T& t) { using U = remove_cvref<T>; pop( t, is_trivially_copy_assignable<U>() ); } private: template<class T> void push( T const& t, std::true_type); template<class T> void push( T&& t, std::false_type); template<class T> void pop( T& t, std::true_type); template<class T> void pop( T& t, std::false_type); BOOST_JSON_DECL void reserve_impl( std::size_t n); }; } // detail } // namespace json } // namespace boost #include <boost/json/detail/impl/stack.hpp> #endif