Loading files
f2929057eThis file is pinned to the selected release. Download the original to open it in your design tool.
// Copyright (c) 2023 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _NCollection_OccAllocator_HeaderFile
#define _NCollection_OccAllocator_HeaderFile
#include <NCollection_BaseAllocator.hxx>
#include <Standard.hxx>
#include <memory>
#include <type_traits>
//! Implements allocator requirements as defined in ISO C++ Standard 2003, section 20.1.5.
/*! The allocator uses a standard OCCT mechanism for memory
allocation and deallocation. It can be used with standard
containers (std::vector, std::map, etc.) to take advantage of OCCT memory optimizations.
Example of use:
\code
NCollection_OccAllocator<TopoDS_Shape> anSAllocator();
std::list<TopoDS_Shape, NCollection_OccAllocator<TopoDS_Shape>> aList(anSAllocator);
TopoDS_Solid aSolid = BRepPrimAPI_MakeBox(10., 20., 30.);
aList.push_back(aSolid);
\endcode
*/
template <typename ItemType>
class NCollection_OccAllocator
{
public:
typedef ItemType value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::false_type propagate_on_container_move_assignment; // std::false_type
template <typename OtherType>
struct rebind
{
typedef NCollection_OccAllocator<OtherType> other;
};
//! Constructor.
//! Creates an object using the default Open CASCADE allocation mechanism, i.e., which uses
//! Standard::Allocate() and Standard::Free() underneath.
NCollection_OccAllocator() noexcept
: myAllocator(nullptr)
{
}
//! Constructor.
NCollection_OccAllocator(const occ::handle<NCollection_BaseAllocator>& theAlloc)
: myAllocator(theAlloc)
{
}
//! Constructor.
NCollection_OccAllocator(occ::handle<NCollection_BaseAllocator>&& theAlloc)
: myAllocator(theAlloc)
{
}
//! Constructor.
NCollection_OccAllocator(const NCollection_OccAllocator& theOther)
= default;
//! Constructor.
NCollection_OccAllocator(NCollection_OccAllocator&& theOther) noexcept
: myAllocator(theOther.myAllocator)
{
}
//! Assignment operator
NCollection_OccAllocator& operator=(const NCollection_OccAllocator& theOther) = default;
//! Assignment operator
NCollection_OccAllocator& operator=(NCollection_OccAllocator&& theOther) noexcept
{
myAllocator = theOther.myAllocator;
return *this;
}
//! Assignment operator
template <typename OtherType>
NCollection_OccAllocator& operator=(const NCollection_OccAllocator<OtherType>& theOther)
{
myAllocator = theOther.myAllocator;
return *this;
}
//! Constructor.
//! Creates an object using the default Open CASCADE allocation mechanism, i.e., which uses
//! Standard::Allocate() and Standard::Free() underneath.
template <typename OtherType>
NCollection_OccAllocator(const NCollection_OccAllocator<OtherType>& theOther)
: myAllocator(theOther.Allocator())
{
}
void SetAllocator(const occ::handle<NCollection_BaseAllocator>& theAlloc)
{
myAllocator = theAlloc;
}
const occ::handle<NCollection_BaseAllocator>& Allocator() const noexcept { return myAllocator; }
//! Allocates memory for theSize objects.
pointer allocate(size_type theSize, const void* = nullptr)
{
return static_cast<pointer>(myAllocator.IsNull()
? Standard::AllocateOptimal(theSize * sizeof(ItemType))
: myAllocator->AllocateOptimal(theSize * sizeof(ItemType)));
}
//! Template version of function Free(), nullifies the argument pointer
//! @param thePtr - previously allocated memory block to be freed
template <typename T>
void deallocate(T* thePnt, size_type)
{
myAllocator.IsNull() ? Standard::Free(thePnt) : myAllocator->Free(thePnt);
}
//! Frees previously allocated memory.
void deallocate(pointer thePnt, size_type)
{
typedef typename std::remove_const<value_type>::type non_const_value_type;
non_const_value_type* aPnt = const_cast<non_const_value_type*>(thePnt);
myAllocator.IsNull() ? Standard::Free(aPnt) : myAllocator->Free(aPnt);
}
//! Constructs an object.
//! Uses placement new operator and copy constructor to construct an object.
template <class _Objty, class... _Types>
void construct(_Objty* _Ptr, _Types&&... _Args)
{
::new ((void*)_Ptr) _Objty(std::forward<_Types>(_Args)...);
}
//! Returns an object address.
template <typename Type = value_type>
typename std::enable_if<!std::is_const<Type>::value, pointer>::type address(
reference theItem) const noexcept
{
return &theItem;
}
//! Returns an object address.
const_pointer address(const_reference theItem) const noexcept { return &theItem; }
//! Destroys the object.
//! Uses the object destructor.
template <class _Uty>
void destroy(_Uty* _Ptr) noexcept(std::is_nothrow_destructible<_Uty>::value)
{
(void)_Ptr;
_Ptr->~_Uty();
}
//! Estimate maximum array size
size_t max_size() const noexcept { return ((size_t)(-1) / sizeof(ItemType)); }
bool operator==(const NCollection_OccAllocator& theOther) const noexcept
{
return theOther.Allocator() == myAllocator;
}
template <class U>
bool operator==(const NCollection_OccAllocator<U>& theOther) const noexcept
{
return theOther.Allocator() == myAllocator;
}
bool operator!=(const NCollection_OccAllocator& theOther) const noexcept
{
return theOther.Allocator() != myAllocator;
}
template <class U>
bool operator!=(const NCollection_OccAllocator<U>& theOther) const noexcept
{
return theOther.Allocator() != myAllocator;
}
private:
occ::handle<NCollection_BaseAllocator> myAllocator;
};
template <class U, class V>
bool operator==(const NCollection_OccAllocator<U>& theFirst,
const NCollection_OccAllocator<V>& theSecond) noexcept
{
return theFirst.Allocator() == theSecond.Allocator();
}
#endif