Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-12 09:18:06

0001 // Copyright (c) 2023 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _NCollection_OccAllocator_HeaderFile
0015 #define _NCollection_OccAllocator_HeaderFile
0016 
0017 #include <NCollection_BaseAllocator.hxx>
0018 #include <Standard.hxx>
0019 
0020 #include <memory>
0021 #include <type_traits>
0022 
0023 //! Implements allocator requirements as defined in ISO C++ Standard 2003, section 20.1.5.
0024 /*! The allocator uses a standard OCCT mechanism for memory
0025   allocation and deallocation. It can be used with standard
0026   containers (std::vector, std::map, etc.) to take advantage of OCCT memory optimizations.
0027 
0028   Example of use:
0029   \code
0030   NCollection_OccAllocator<TopoDS_Shape> anSAllocator();
0031   std::list<TopoDS_Shape, NCollection_OccAllocator<TopoDS_Shape>> aList(anSAllocator);
0032   TopoDS_Solid aSolid = BRepPrimAPI_MakeBox(10., 20., 30.);
0033   aList.push_back(aSolid);
0034   \endcode
0035 */
0036 template <typename ItemType>
0037 class NCollection_OccAllocator
0038 {
0039 public:
0040   typedef ItemType          value_type;
0041   typedef value_type*       pointer;
0042   typedef const value_type* const_pointer;
0043   typedef value_type&       reference;
0044   typedef const value_type& const_reference;
0045   typedef size_t            size_type;
0046   typedef ptrdiff_t         difference_type;
0047   typedef std::false_type   propagate_on_container_move_assignment; // std::false_type
0048 
0049   template <typename OtherType>
0050   struct rebind
0051   {
0052     typedef NCollection_OccAllocator<OtherType> other;
0053   };
0054 
0055   //! Constructor.
0056   //! Creates an object using the default Open CASCADE allocation mechanism, i.e., which uses
0057   //! Standard::Allocate() and Standard::Free() underneath.
0058   NCollection_OccAllocator() noexcept
0059       : myAllocator(nullptr)
0060   {
0061   }
0062 
0063   //! Constructor.
0064   NCollection_OccAllocator(const occ::handle<NCollection_BaseAllocator>& theAlloc)
0065       : myAllocator(theAlloc)
0066   {
0067   }
0068 
0069   //! Constructor.
0070   NCollection_OccAllocator(occ::handle<NCollection_BaseAllocator>&& theAlloc)
0071       : myAllocator(theAlloc)
0072   {
0073   }
0074 
0075   //! Constructor.
0076   NCollection_OccAllocator(const NCollection_OccAllocator& theOther)
0077 
0078     = default;
0079 
0080   //! Constructor.
0081   NCollection_OccAllocator(NCollection_OccAllocator&& theOther) noexcept
0082       : myAllocator(theOther.myAllocator)
0083   {
0084   }
0085 
0086   //! Assignment operator
0087   NCollection_OccAllocator& operator=(const NCollection_OccAllocator& theOther) = default;
0088 
0089   //! Assignment operator
0090   NCollection_OccAllocator& operator=(NCollection_OccAllocator&& theOther) noexcept
0091   {
0092     myAllocator = theOther.myAllocator;
0093     return *this;
0094   }
0095 
0096   //! Assignment operator
0097   template <typename OtherType>
0098   NCollection_OccAllocator& operator=(const NCollection_OccAllocator<OtherType>& theOther)
0099   {
0100     myAllocator = theOther.myAllocator;
0101     return *this;
0102   }
0103 
0104   //! Constructor.
0105   //! Creates an object using the default Open CASCADE allocation mechanism, i.e., which uses
0106   //! Standard::Allocate() and Standard::Free() underneath.
0107   template <typename OtherType>
0108   NCollection_OccAllocator(const NCollection_OccAllocator<OtherType>& theOther)
0109       : myAllocator(theOther.Allocator())
0110   {
0111   }
0112 
0113   void SetAllocator(const occ::handle<NCollection_BaseAllocator>& theAlloc)
0114   {
0115     myAllocator = theAlloc;
0116   }
0117 
0118   const occ::handle<NCollection_BaseAllocator>& Allocator() const noexcept { return myAllocator; }
0119 
0120   //! Allocates memory for theSize objects.
0121   pointer allocate(size_type theSize, const void* = nullptr)
0122   {
0123     return static_cast<pointer>(myAllocator.IsNull()
0124                                   ? Standard::AllocateOptimal(theSize * sizeof(ItemType))
0125                                   : myAllocator->AllocateOptimal(theSize * sizeof(ItemType)));
0126   }
0127 
0128   //! Template version of function Free(), nullifies the argument pointer
0129   //! @param thePtr - previously allocated memory block to be freed
0130   template <typename T>
0131   void deallocate(T* thePnt, size_type)
0132   {
0133     myAllocator.IsNull() ? Standard::Free(thePnt) : myAllocator->Free(thePnt);
0134   }
0135 
0136   //! Frees previously allocated memory.
0137   void deallocate(pointer thePnt, size_type)
0138   {
0139     typedef typename std::remove_const<value_type>::type non_const_value_type;
0140     non_const_value_type* aPnt = const_cast<non_const_value_type*>(thePnt);
0141     myAllocator.IsNull() ? Standard::Free(aPnt) : myAllocator->Free(aPnt);
0142   }
0143 
0144   //! Constructs an object.
0145   //! Uses placement new operator and copy constructor to construct an object.
0146   template <class _Objty, class... _Types>
0147   void construct(_Objty* _Ptr, _Types&&... _Args)
0148   {
0149     ::new ((void*)_Ptr) _Objty(std::forward<_Types>(_Args)...);
0150   }
0151 
0152   //! Returns an object address.
0153   template <typename Type = value_type>
0154   typename std::enable_if<!std::is_const<Type>::value, pointer>::type address(
0155     reference theItem) const noexcept
0156   {
0157     return &theItem;
0158   }
0159 
0160   //! Returns an object address.
0161   const_pointer address(const_reference theItem) const noexcept { return &theItem; }
0162 
0163   //! Destroys the object.
0164   //! Uses the object destructor.
0165   template <class _Uty>
0166   void destroy(_Uty* _Ptr) noexcept(std::is_nothrow_destructible<_Uty>::value)
0167   {
0168     (void)_Ptr;
0169     _Ptr->~_Uty();
0170   }
0171 
0172   //! Estimate maximum array size
0173   size_t max_size() const noexcept { return ((size_t)(-1) / sizeof(ItemType)); }
0174 
0175   bool operator==(const NCollection_OccAllocator& theOther) const noexcept
0176   {
0177     return theOther.Allocator() == myAllocator;
0178   }
0179 
0180   template <class U>
0181   bool operator==(const NCollection_OccAllocator<U>& theOther) const noexcept
0182   {
0183     return theOther.Allocator() == myAllocator;
0184   }
0185 
0186   bool operator!=(const NCollection_OccAllocator& theOther) const noexcept
0187   {
0188     return theOther.Allocator() != myAllocator;
0189   }
0190 
0191   template <class U>
0192   bool operator!=(const NCollection_OccAllocator<U>& theOther) const noexcept
0193   {
0194     return theOther.Allocator() != myAllocator;
0195   }
0196 
0197 private:
0198   occ::handle<NCollection_BaseAllocator> myAllocator;
0199 };
0200 
0201 template <class U, class V>
0202 bool operator==(const NCollection_OccAllocator<U>& theFirst,
0203                 const NCollection_OccAllocator<V>& theSecond) noexcept
0204 {
0205   return theFirst.Allocator() == theSecond.Allocator();
0206 }
0207 
0208 #endif