]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/json/monotonic_resource.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / json / monotonic_resource.hpp
diff --git a/ceph/src/boost/boost/json/monotonic_resource.hpp b/ceph/src/boost/boost/json/monotonic_resource.hpp
new file mode 100644 (file)
index 0000000..8ecb017
--- /dev/null
@@ -0,0 +1,350 @@
+//
+// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
+// Copyright (c) 2020 Krystian Stasiowski (sdkrystian@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_MONOTONIC_RESOURCE_HPP
+#define BOOST_JSON_MONOTONIC_RESOURCE_HPP
+
+#include <boost/json/detail/config.hpp>
+#include <boost/json/memory_resource.hpp>
+#include <boost/json/storage_ptr.hpp>
+#include <cstddef>
+#include <utility>
+
+BOOST_JSON_NS_BEGIN
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4251) // class needs to have dll-interface to be used by clients of class
+#pragma warning(disable: 4275) // non dll-interface class used as base for dll-interface class 
+#endif
+
+//----------------------------------------------------------
+
+/** A dynamically allocating resource with a trivial deallocate
+
+    This memory resource is a special-purpose resource
+    that releases allocated memory only when the resource
+    is destroyed (or when @ref release is called).
+    It has a trivial deallocate function; that is, the
+    metafunction @ref is_deallocate_trivial returns `true`.
+\n
+    The resource can be constructed with an initial buffer.
+    If there is no initial buffer, or if the buffer is
+    exhausted, subsequent dynamic allocations are made from
+    the system heap. The size of buffers obtained in this
+    fashion follow a geometric progression.
+\n
+    The purpose of this resource is to optimize the use
+    case for performing many allocations, followed by
+    deallocating everything at once. This is precisely the
+    pattern of memory allocation which occurs when parsing:
+    allocation is performed for each parsed element, and
+    when the the resulting @ref value is no longer needed,
+    the entire structure is destroyed. However, it is not
+    suited for modifying the value after parsing is
+    complete; reallocations waste memory, since the
+    older buffer is not reclaimed until the resource
+    is destroyed.
+
+    @par Example
+
+    This parses a JSON into a value which uses a local
+    stack buffer, then prints the result.
+
+    @code
+
+    unsigned char buf[ 4000 ];
+    monotonic_resource mr( buf );
+
+    // Parse the string, using our memory resource
+    auto const jv = parse( "[1,2,3]", &mr );
+
+    // Print the JSON
+    std::cout << jv;
+
+    @endcode
+
+    @note The total amount of memory dynamically
+    allocated is monotonically increasing; That is,
+    it never decreases.
+
+    @par Thread Safety
+    Members of the same instance may not be
+    called concurrently.
+
+    @see
+        https://en.wikipedia.org/wiki/Region-based_memory_management
+*/
+class BOOST_JSON_CLASS_DECL
+    monotonic_resource final
+    : public memory_resource
+{   
+    struct block;
+    struct block_base
+    {
+        void* p;
+        std::size_t avail;
+        std::size_t size;
+        block_base* next;
+    };
+
+    block_base buffer_;
+    block_base* head_ = &buffer_;
+    std::size_t next_size_ = 1024;
+    storage_ptr upstream_;
+
+    static constexpr std::size_t min_size_ = 1024;
+    inline static constexpr std::size_t max_size();
+    inline static std::size_t round_pow2(
+        std::size_t n) noexcept;
+    inline static std::size_t next_pow2(
+        std::size_t n) noexcept;
+
+public:
+    /// Copy constructor (deleted)
+    monotonic_resource(
+        monotonic_resource const&) = delete;
+
+    /// Copy assignment (deleted)
+    monotonic_resource& operator=(
+        monotonic_resource const&) = delete;
+
+    /** Destructor
+
+        Deallocates all the memory owned by this resource.
+
+        @par Effects
+        @code
+        this->release();
+        @endcode
+
+        @par Complexity
+        Linear in the number of deallocations performed.
+
+        @par Exception Safety
+        No-throw guarantee.
+    */
+    ~monotonic_resource();
+
+    /** Constructor
+
+        This constructs the resource and indicates
+        that the first internal dynamic allocation
+        shall be at least `initial_size` bytes.
+    \n
+        This constructor is guaranteed not to perform
+        any dynamic allocations.
+
+        @par Complexity
+        Constant.
+
+        @par Exception Safety
+        No-throw guarantee.
+
+        @param initial_size The size of the first
+        internal dynamic allocation. If this is lower
+        than the implementation-defined lower limit, then
+        the lower limit is used instead.
+
+        @param upstream An optional upstream memory resource
+        to use for performing internal dynamic allocations.
+        If this parameter is omitted, the default resource
+        is used.
+    */
+    explicit
+    monotonic_resource(
+        std::size_t initial_size = 1024,
+        storage_ptr upstream = {}) noexcept;
+
+    /** Constructor
+
+        This constructs the resource and indicates that
+        subsequent allocations should use the specified
+        caller-owned buffer.
+        When this buffer is exhausted, dynamic allocations
+        from the upstream resource are made.
+    \n
+        This constructor is guaranteed not to perform
+        any dynamic allocations.
+
+        @par Complexity
+        Constant.
+
+        @par Exception Safety
+        No-throw guarantee.
+
+        @param buffer The buffer to use.
+        Ownership is not transferred; the caller is
+        responsible for ensuring that the lifetime of
+        the buffer extends until the resource is destroyed.
+
+        @param size The number of valid bytes pointed
+        to by `buffer`.
+
+        @param upstream An optional upstream memory resource
+        to use for performing internal dynamic allocations.
+        If this parameter is omitted, the default resource
+        is used.
+    */
+    /** @{ */
+    monotonic_resource(
+        unsigned char* buffer,
+        std::size_t size,
+        storage_ptr upstream = {}) noexcept;
+
+#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+    monotonic_resource(
+        std::byte* buffer,
+        std::size_t size,
+        storage_ptr upstream) noexcept
+        : monotonic_resource(reinterpret_cast<
+            unsigned char*>(buffer), size,
+                std::move(upstream))
+    {
+    }
+#endif
+    /** @} */
+
+    /** Constructor
+
+        This constructs the resource and indicates that
+        subsequent allocations should use the specified
+        caller-owned buffer.
+        When this buffer is exhausted, dynamic allocations
+        from the upstream resource are made.
+    \n
+        This constructor is guaranteed not to perform
+        any dynamic allocations.
+
+        @par Complexity
+        Constant.
+
+        @par Exception Safety
+        No-throw guarantee.
+
+        @param buffer The buffer to use.
+        Ownership is not transferred; the caller is
+        responsible for ensuring that the lifetime of
+        the buffer extends until the resource is destroyed.
+
+        @param upstream An optional upstream memory resource
+        to use for performing internal dynamic allocations.
+        If this parameter is omitted, the default resource
+        is used.
+    */
+    /** @{ */
+    template<std::size_t N>
+    explicit
+    monotonic_resource(
+        unsigned char(&buffer)[N],
+        storage_ptr upstream = {}) noexcept
+        : monotonic_resource(&buffer[0],
+            N, std::move(upstream))
+    {
+    }
+
+#if defined(__cpp_lib_byte) || defined(BOOST_JSON_DOCS)
+    template<std::size_t N>
+    explicit
+    monotonic_resource(
+        std::byte(&buffer)[N],
+        storage_ptr upstream = {}) noexcept
+        : monotonic_resource(&buffer[0],
+            N, std::move(upstream))
+    {
+    }
+#endif
+    /** @} */
+
+#ifndef BOOST_JSON_DOCS
+    // Safety net for accidental buffer overflows
+    template<std::size_t N>
+    monotonic_resource(
+        unsigned char(&buffer)[N],
+        std::size_t n,
+        storage_ptr upstream = {}) noexcept
+        : monotonic_resource(&buffer[0],
+            n, std::move(upstream))
+    {
+        // If this goes off, check your parameters
+        // closely, chances are you passed an array
+        // thinking it was a pointer.
+        BOOST_ASSERT(n <= N);
+    }
+
+#ifdef __cpp_lib_byte
+    // Safety net for accidental buffer overflows
+    template<std::size_t N>
+    monotonic_resource(
+        std::byte(&buffer)[N],
+        std::size_t n,
+        storage_ptr upstream = {}) noexcept
+        : monotonic_resource(&buffer[0],
+            n, std::move(upstream))
+    {
+        // If this goes off, check your parameters
+        // closely, chances are you passed an array
+        // thinking it was a pointer.
+        BOOST_ASSERT(n <= N);
+    }
+#endif
+#endif
+
+    /** Release all allocated memory.
+
+        This function deallocates all allocated memory.
+        If an initial buffer was provided upon construction,
+        then all of the bytes will be available again for
+        allocation. Allocated memory is deallocated even
+        if deallocate has not been called for some of
+        the allocated blocks.
+
+        @par Complexity
+        Linear in the number of deallocations performed.
+
+        @par Exception Safety
+        No-throw guarantee.
+    */
+    void
+    release() noexcept;
+
+protected:
+#ifndef BOOST_JSON_DOCS
+    void*
+    do_allocate(
+        std::size_t n,
+        std::size_t align) override;
+
+    void
+    do_deallocate(
+        void* p,
+        std::size_t n,
+        std::size_t align) override;
+
+    bool
+    do_is_equal(
+        memory_resource const& mr) const noexcept override;
+#endif
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+template<>
+struct is_deallocate_trivial<
+    monotonic_resource>
+{
+    static constexpr bool value = true;
+};
+
+BOOST_JSON_NS_END
+
+#endif