///////////////////////////////////////////////////////////////////////////// // Copyright (c) Electronic Arts Inc. All rights reserved. ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // This file implements a map and multimap which use a fixed size memory // pool for their nodes. /////////////////////////////////////////////////////////////////////////////// #ifndef EASTL_FIXED_MAP_H #define EASTL_FIXED_MAP_H #include #include // Included because fixed_rbtree_base resides here. #if defined(EA_PRAGMA_ONCE_SUPPORTED) #pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result. #endif namespace eastl { /// EASTL_FIXED_MAP_DEFAULT_NAME /// /// Defines a default container name in the absence of a user-provided name. /// In the case of fixed-size containers, the allocator name always refers /// to overflow allocations. /// #ifndef EASTL_FIXED_MAP_DEFAULT_NAME #define EASTL_FIXED_MAP_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_map" // Unless the user overrides something, this is "EASTL fixed_map". #endif #ifndef EASTL_FIXED_MULTIMAP_DEFAULT_NAME #define EASTL_FIXED_MULTIMAP_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_multimap" // Unless the user overrides something, this is "EASTL fixed_multimap". #endif /// EASTL_FIXED_MAP_DEFAULT_ALLOCATOR /// EASTL_FIXED_MULTIMAP_DEFAULT_ALLOCATOR /// #ifndef EASTL_FIXED_MAP_DEFAULT_ALLOCATOR #define EASTL_FIXED_MAP_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_MAP_DEFAULT_NAME) #endif #ifndef EASTL_FIXED_MULTIMAP_DEFAULT_ALLOCATOR #define EASTL_FIXED_MULTIMAP_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_MULTIMAP_DEFAULT_NAME) #endif /// fixed_map /// /// Implements a map with a fixed block of memory identified by the /// nodeCount template parameter. /// /// Key The key object (key in the key/value pair). /// T The mapped object (value in the key/value pair). /// nodeCount The max number of objects to contain. /// bEnableOverflow Whether or not we should use the global heap if our object pool is exhausted. /// Compare Compare function/object for set ordering. /// OverflowAllocator Overflow allocator, which is only used if bEnableOverflow == true. Defaults to the global heap. /// template , typename OverflowAllocator = EASTLAllocatorType> class fixed_map : public map::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair), 0, bEnableOverflow, OverflowAllocator> > { public: typedef fixed_node_allocator::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair), 0, bEnableOverflow, OverflowAllocator> fixed_allocator_type; typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type; typedef fixed_map this_type; typedef map base_type; typedef typename base_type::value_type value_type; typedef typename base_type::node_type node_type; typedef typename base_type::size_type size_type; enum { kMaxSize = nodeCount }; using base_type::insert; protected: char mBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements. using base_type::mAllocator; public: fixed_map(); explicit fixed_map(const overflow_allocator_type& overflowAllocator); explicit fixed_map(const Compare& compare); fixed_map(const this_type& x); fixed_map(this_type&& x); fixed_map(this_type&& x, const overflow_allocator_type& overflowAllocator); fixed_map(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_MAP_DEFAULT_ALLOCATOR); template fixed_map(InputIterator first, InputIterator last); this_type& operator=(const this_type& x); this_type& operator=(std::initializer_list ilist); this_type& operator=(this_type&& x); void swap(this_type& x); void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs. size_type max_size() const; const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT; overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT; void set_overflow_allocator(const overflow_allocator_type& allocator); }; // fixed_map /// fixed_multimap /// /// Implements a multimap with a fixed block of memory identified by the /// nodeCount template parameter. /// /// Key The key object (key in the key/value pair). /// T The mapped object (value in the key/value pair). /// nodeCount The max number of objects to contain. /// bEnableOverflow Whether or not we should use the global heap if our object pool is exhausted. /// Compare Compare function/object for set ordering. /// OverflowAllocator Overflow allocator, which is only used if bEnableOverflow == true. Defaults to the global heap. /// template , typename OverflowAllocator = EASTLAllocatorType> class fixed_multimap : public multimap::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair), 0, bEnableOverflow, OverflowAllocator> > { public: typedef fixed_node_allocator::node_type), nodeCount, EASTL_ALIGN_OF(eastl::pair), 0, bEnableOverflow, OverflowAllocator> fixed_allocator_type; typedef typename fixed_allocator_type::overflow_allocator_type overflow_allocator_type; typedef multimap base_type; typedef fixed_multimap this_type; typedef typename base_type::value_type value_type; typedef typename base_type::node_type node_type; typedef typename base_type::size_type size_type; enum { kMaxSize = nodeCount }; using base_type::insert; protected: char mBuffer[fixed_allocator_type::kBufferSize]; // kBufferSize will take into account alignment requirements. using base_type::mAllocator; using base_type::get_compare; public: fixed_multimap(); fixed_multimap(const overflow_allocator_type& overflowAllocator); explicit fixed_multimap(const Compare& compare); fixed_multimap(const this_type& x); fixed_multimap(this_type&& x); fixed_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator); fixed_multimap(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator = EASTL_FIXED_MULTIMAP_DEFAULT_ALLOCATOR); template fixed_multimap(InputIterator first, InputIterator last); this_type& operator=(const this_type& x); this_type& operator=(std::initializer_list ilist); this_type& operator=(this_type&& x); void swap(this_type& x); void reset_lose_memory(); // This is a unilateral reset to an initially empty state. No destructors are called, no deallocation occurs. size_type max_size() const; const overflow_allocator_type& get_overflow_allocator() const EA_NOEXCEPT; overflow_allocator_type& get_overflow_allocator() EA_NOEXCEPT; void set_overflow_allocator(const overflow_allocator_type& allocator); }; // fixed_multimap /////////////////////////////////////////////////////////////////////// // fixed_map /////////////////////////////////////////////////////////////////////// template inline fixed_map::fixed_map() : base_type(fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MAP_DEFAULT_NAME); #endif } template inline fixed_map::fixed_map(const overflow_allocator_type& overflowAllocator) : base_type(fixed_allocator_type(mBuffer, overflowAllocator)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MAP_DEFAULT_NAME); #endif } template inline fixed_map::fixed_map(const Compare& compare) : base_type(compare, fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MAP_DEFAULT_NAME); #endif } template inline fixed_map::fixed_map(const this_type& x) : base_type(x.get_compare(), fixed_allocator_type(mBuffer)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template inline fixed_map::fixed_map(this_type&& x) : base_type(x.get_compare(), fixed_allocator_type(mBuffer)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template inline fixed_map::fixed_map(this_type&& x, const overflow_allocator_type& overflowAllocator) : base_type(x.get_compare(), fixed_allocator_type(mBuffer, overflowAllocator)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template fixed_map::fixed_map(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator) : base_type(fixed_allocator_type(mBuffer, overflowAllocator)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MAP_DEFAULT_NAME); #endif insert(ilist.begin(), ilist.end()); } template template fixed_map::fixed_map(InputIterator first, InputIterator last) : base_type(fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MAP_DEFAULT_NAME); #endif insert(first, last); } template inline typename fixed_map::this_type& fixed_map::operator=(const this_type& x) { base_type::operator=(x); return *this; } template inline typename fixed_map::this_type& fixed_map::operator=(std::initializer_list ilist) { base_type::clear(); insert(ilist.begin(), ilist.end()); return *this; } template inline typename fixed_map::this_type& fixed_map::operator=(this_type&& x) { base_type::operator=(x); return *this; } template inline void fixed_map::swap(this_type& x) { // Fixed containers use a special swap that can deal with excessively large buffers. eastl::fixed_swap(*this, x); } template inline void fixed_map::reset_lose_memory() { base_type::reset_lose_memory(); base_type::get_allocator().reset(mBuffer); } template inline typename fixed_map::size_type fixed_map::max_size() const { return kMaxSize; } template inline const typename fixed_map::overflow_allocator_type& fixed_map::get_overflow_allocator() const EA_NOEXCEPT { return mAllocator.get_overflow_allocator(); } template inline typename fixed_map::overflow_allocator_type& fixed_map::get_overflow_allocator() EA_NOEXCEPT { return mAllocator.get_overflow_allocator(); } template inline void fixed_map::set_overflow_allocator(const overflow_allocator_type& allocator) { mAllocator.set_overflow_allocator(allocator); } /////////////////////////////////////////////////////////////////////// // global operators /////////////////////////////////////////////////////////////////////// template inline void swap(fixed_map& a, fixed_map& b) { // Fixed containers use a special swap that can deal with excessively large buffers. eastl::fixed_swap(a, b); } /////////////////////////////////////////////////////////////////////// // fixed_multimap /////////////////////////////////////////////////////////////////////// template inline fixed_multimap::fixed_multimap() : base_type(fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MULTIMAP_DEFAULT_NAME); #endif } template inline fixed_multimap::fixed_multimap(const overflow_allocator_type& overflowAllocator) : base_type(fixed_allocator_type(mBuffer, overflowAllocator)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MULTIMAP_DEFAULT_NAME); #endif } template inline fixed_multimap::fixed_multimap(const Compare& compare) : base_type(compare, fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MULTIMAP_DEFAULT_NAME); #endif } template inline fixed_multimap::fixed_multimap(const this_type& x) : base_type(x.get_compare(), fixed_allocator_type(mBuffer)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template inline fixed_multimap::fixed_multimap(this_type&& x) : base_type(x.get_compare(), fixed_allocator_type(mBuffer)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template inline fixed_multimap::fixed_multimap(this_type&& x, const overflow_allocator_type& overflowAllocator) : base_type(x.get_compare(), fixed_allocator_type(mBuffer, overflowAllocator)) { mAllocator.copy_overflow_allocator(x.mAllocator); #if EASTL_NAME_ENABLED mAllocator.set_name(x.mAllocator.get_name()); #endif base_type::operator=(x); } template fixed_multimap::fixed_multimap(std::initializer_list ilist, const overflow_allocator_type& overflowAllocator) : base_type(fixed_allocator_type(mBuffer, overflowAllocator)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MULTIMAP_DEFAULT_NAME); #endif insert(ilist.begin(), ilist.end()); } template template fixed_multimap:: fixed_multimap(InputIterator first, InputIterator last) : base_type(fixed_allocator_type(mBuffer)) { #if EASTL_NAME_ENABLED mAllocator.set_name(EASTL_FIXED_MULTIMAP_DEFAULT_NAME); #endif insert(first, last); } template inline typename fixed_multimap::this_type& fixed_multimap::operator=(const this_type& x) { base_type::operator=(x); return *this; } template inline typename fixed_multimap::this_type& fixed_multimap::operator=(std::initializer_list ilist) { base_type::clear(); insert(ilist.begin(), ilist.end()); return *this; } template inline typename fixed_multimap::this_type& fixed_multimap::operator=(this_type&& x) { base_type::operator=(x); return *this; } template inline void fixed_multimap::swap(this_type& x) { // Fixed containers use a special swap that can deal with excessively large buffers. eastl::fixed_swap(*this, x); } template inline void fixed_multimap::reset_lose_memory() { base_type::reset_lose_memory(); base_type::get_allocator().reset(mBuffer); } template inline typename fixed_multimap::size_type fixed_multimap::max_size() const { return kMaxSize; } template inline const typename fixed_multimap::overflow_allocator_type& fixed_multimap::get_overflow_allocator() const EA_NOEXCEPT { return mAllocator.get_overflow_allocator(); } template inline typename fixed_multimap::overflow_allocator_type& fixed_multimap::get_overflow_allocator() EA_NOEXCEPT { return mAllocator.get_overflow_allocator(); } template inline void fixed_multimap::set_overflow_allocator(const overflow_allocator_type& allocator) { mAllocator.set_overflow_allocator(allocator); } /////////////////////////////////////////////////////////////////////// // global operators /////////////////////////////////////////////////////////////////////// template inline void swap(fixed_multimap& a, fixed_multimap& b) { // Fixed containers use a special swap that can deal with excessively large buffers. eastl::fixed_swap(a, b); } } // namespace eastl #endif // Header include guard