Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Gaudi/Allocator/Arena.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***********************************************************************************\
0002 * (c) Copyright 2019-20 CERN for the benefit of the LHCb and ATLAS collaborations   *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #pragma once
0012 #include <cstddef>
0013 #include <functional>
0014 #include <type_traits>
0015 namespace Gaudi::Allocator {
0016   /** @class Arena
0017    *  @brief Custom allocator holding a pointer to a generic memory resource.
0018    *
0019    *  Custom allocator holding a pointer to a memory resource ("arena").
0020    *  Allocation and deallocation requests are passed through to the arena.
0021    *  Note that the typedefs propagate_on_container_{swap,copy_assignment,move_assignment}
0022    *  do not have their default values.
0023    *
0024    *  The, optional, third template parameter (DefaultResource) may be used to specify
0025    *  a default arena, in which case the allocator is default-constructible. Otherwise,
0026    *  a pointer to an arena must be given.
0027    */
0028   template <typename Resource, typename T, typename DefaultResource = void>
0029   struct Arena {
0030     using value_type                             = T;
0031     using propagate_on_container_swap            = std::true_type;
0032     using propagate_on_container_copy_assignment = std::true_type;
0033     using propagate_on_container_move_assignment = std::true_type;
0034 
0035     /** Construct an allocator using the given memory resource, which must be valid.
0036      */
0037     constexpr Arena( Resource* resource ) noexcept : m_resource{ resource } {}
0038 
0039     /** Construct an allocator using the resource provided by DefaultResource.
0040      *  This constructor is only enabled if an instance of DefaultResource can be invoked
0041      *  with no arguments and yields Resource*.
0042      */
0043     template <typename D = void>
0044       requires( std::is_invocable_r_v<Resource*, DefaultResource> )
0045     Arena() : Arena( std::invoke( DefaultResource{} ) ) {}
0046 
0047     /** Converting copy constructor, rebinding U -> T.
0048      */
0049     template <typename U>
0050     constexpr Arena( Arena<Resource, U, DefaultResource> const& other ) noexcept : m_resource{ other.m_resource } {}
0051 
0052     /** Allocate storage for n objects.
0053      */
0054     [[nodiscard]] T* allocate( std::size_t n ) {
0055       return reinterpret_cast<T*>( m_resource->template allocate<alignof( T )>( n * sizeof( T ) ) );
0056     }
0057 
0058     /** Deallocate storage for n objects.
0059      */
0060     void deallocate( T* p, std::size_t n ) noexcept {
0061       m_resource->deallocate( reinterpret_cast<std::byte*>( p ), n * sizeof( T ) );
0062     }
0063 
0064     /** Return a pointer to the memory resource.
0065      */
0066     [[nodiscard]] Resource* resource() const noexcept { return m_resource; }
0067 
0068     template <typename U>
0069     friend constexpr bool operator==( Arena const& lhs, Arena<Resource, U, DefaultResource> const& rhs ) {
0070       return lhs.m_resource == rhs.m_resource;
0071     }
0072 
0073     template <typename U>
0074     struct rebind {
0075       using other = Arena<Resource, U, DefaultResource>;
0076     };
0077 
0078   private:
0079     // Required for the Arena<Resource, U, DefaultResource> converting copy constructor
0080     template <typename, typename, typename>
0081     friend struct Arena;
0082 
0083     Resource* m_resource{ nullptr };
0084   };
0085 
0086   template <typename Resource, typename T, typename U, typename DefaultResource>
0087   inline constexpr bool operator!=( Arena<Resource, T, DefaultResource> const& lhs,
0088                                     Arena<Resource, U, DefaultResource> const& rhs ) {
0089     return !( lhs == rhs );
0090   }
0091 } // namespace Gaudi::Allocator