Nugget
fixed_tuple_vector.h
1 // Copyright (c) Electronic Arts Inc. All rights reserved.
4 
5 #ifndef EASTL_FIXEDTUPLEVECTOR_H
6 #define EASTL_FIXEDTUPLEVECTOR_H
7 
8 #include <EASTL/bonus/tuple_vector.h>
9 #include <EASTL/internal/fixed_pool.h>
10 
11 #if defined(EA_PRAGMA_ONCE_SUPPORTED)
12  #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.
13 #endif
14 
15 namespace eastl
16 {
17 
24  #ifndef EASTL_FIXED_TUPLE_VECTOR_DEFAULT_NAME
25  #define EASTL_FIXED_TUPLE_VECTOR_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " fixed_tuple_vector" // Unless the user overrides something, this is "EASTL fixed_vector".
26  #endif
27 
28 
31  #ifndef EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR
32  #define EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR overflow_allocator_type(EASTL_FIXED_TUPLE_VECTOR_DEFAULT_NAME)
33  #endif
34 
35 // External interface of fixed_tuple_vector
36 template <size_t nodeCount, bool bEnableOverflow, typename... Ts>
37 class fixed_tuple_vector : public TupleVecInternal::TupleVecImpl<fixed_vector_allocator<
38  TupleVecInternal::TupleRecurser<Ts...>::GetTotalAllocationSize(nodeCount, 0), 1,
39  TupleVecInternal::TupleRecurser<Ts...>::GetTotalAlignment(), 0,
40  bEnableOverflow, EASTLAllocatorType>, make_index_sequence<sizeof...(Ts)>, Ts...>
41 {
42 public:
43  typedef fixed_vector_allocator<
44  TupleVecInternal::TupleRecurser<Ts...>::GetTotalAllocationSize(nodeCount, 0), 1,
45  TupleVecInternal::TupleRecurser<Ts...>::GetTotalAlignment(), 0,
46  bEnableOverflow, EASTLAllocatorType> fixed_allocator_type;
48  typedef fixed_tuple_vector<nodeCount, bEnableOverflow, Ts...> this_type;
49  typedef EASTLAllocatorType overflow_allocator_type;
50 
51  typedef TupleVecInternal::TupleVecImpl<fixed_allocator_type, make_index_sequence<sizeof...(Ts)>, Ts...> base_type;
52  typedef typename base_type::size_type size_type;
53 
54 private:
55  aligned_buffer_type mBuffer;
56 
57 public:
59  : base_type(fixed_allocator_type(mBuffer.buffer), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
60  { }
61 
62  fixed_tuple_vector(const overflow_allocator_type& allocator)
63  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
64  { }
65 
67  : base_type(fixed_allocator_type(mBuffer.buffer), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
68  {
69  base_type::get_allocator().copy_overflow_allocator(x.get_allocator());
70  base_type::DoInitFromIterator(make_move_iterator(x.begin()), make_move_iterator(x.end()));
71  x.clear();
72  }
73 
74  fixed_tuple_vector(this_type&& x, const overflow_allocator_type& allocator)
75  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
76  {
77  base_type::DoInitFromIterator(make_move_iterator(x.begin()), make_move_iterator(x.end()));
78  x.clear();
79  }
80 
82  : base_type(fixed_allocator_type(mBuffer.buffer), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
83  {
84  base_type::get_allocator().copy_overflow_allocator(x.get_allocator());
85  base_type::DoInitFromIterator(x.begin(), x.end());
86  }
87 
88  fixed_tuple_vector(const this_type& x, const overflow_allocator_type& allocator)
89  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
90  {
91  base_type::DoInitFromIterator(x.begin(), x.end());
92  }
93 
94  template <typename MoveIterBase>
95  fixed_tuple_vector(move_iterator<MoveIterBase> begin, move_iterator<MoveIterBase> end, const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
96  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
97  {
98  base_type::DoInitFromIterator(begin, end);
99  }
100 
101  template <typename Iterator>
102  fixed_tuple_vector(Iterator begin, Iterator end, const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
103  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
104  {
105  base_type::DoInitFromIterator(begin, end);
106  }
107 
108  fixed_tuple_vector(size_type n, const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
109  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
110  {
111  base_type::DoInitDefaultFill(n);
112  }
113 
114  fixed_tuple_vector(size_type n, const Ts&... args)
115  : base_type(fixed_allocator_type(mBuffer.buffer), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
116  {
117  base_type::DoInitFillArgs(n, args...);
118  }
119 
120  fixed_tuple_vector(size_type n, const Ts&... args, const overflow_allocator_type& allocator)
121  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
122  {
123  base_type::DoInitFillArgs(n, args...);
124  }
125 
126  fixed_tuple_vector(size_type n,
127  typename base_type::const_reference_tuple tup,
128  const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
129  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
130  {
131  base_type::DoInitFillTuple(n, tup);
132  }
133 
134  fixed_tuple_vector(const typename base_type::value_tuple* first, const typename base_type::value_tuple* last,
135  const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
136  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
137  {
138  base_type::DoInitFromTupleArray(first, last);
139  }
140 
142  const overflow_allocator_type& allocator = EASTL_FIXED_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
143  : base_type(fixed_allocator_type(mBuffer.buffer, allocator), mBuffer.buffer, nodeCount, fixed_allocator_type::kNodeSize)
144  {
145  base_type::DoInitFromTupleArray(iList.begin(), iList.end());
146  }
147 
148  this_type& operator=(const this_type& other)
149  {
150  base_type::operator=(other);
151  return *this;
152  }
153 
154  this_type& operator=(this_type&& other)
155  {
156  base_type::clear();
157  // OK to call DoInitFromIterator in a non-ctor scenario because clear() reset everything, more-or-less
158  base_type::DoInitFromIterator(make_move_iterator(other.begin()), make_move_iterator(other.end()));
159  other.clear();
160  return *this;
161  }
162 
164  {
165  base_type::operator=(iList);
166  return *this;
167  }
168 
169  void swap(this_type& x)
170  {
171  // If both containers are using the heap instead of local memory
172  // then we can do a fast pointer swap instead of content swap.
173  if ((has_overflowed() && x.has_overflowed()) && (get_overflow_allocator() == x.get_overflow_allocator()))
174  {
175  base_type::swap(x);
176  }
177  else
178  {
179  // Fixed containers use a special swap that can deal with excessively large buffers.
180  eastl::fixed_swap(*this, x);
181  }
182  }
183 
184  // Returns the max fixed size, which is the user-supplied nodeCount parameter.
185  size_type max_size() const { return nodeCount; }
186  // Returns true if the fixed space has been fully allocated. Note that if overflow is enabled,
187  // the container size can be greater than nodeCount but full() could return true because the
188  // fixed space may have a recently freed slot.
189  bool full() const { return (base_type::mNumElements >= nodeCount) || ((void*)base_type::mpData != (void*)mBuffer.buffer); }
190  // Returns true if the allocations spilled over into the overflow allocator. Meaningful
191  // only if overflow is enabled.
192  bool has_overflowed() const { return ((void*)base_type::mpData != (void*)mBuffer.buffer); }
193  // Returns the value of the bEnableOverflow template parameter.
194  bool can_overflow() const { return bEnableOverflow; }
195 
196  const overflow_allocator_type& get_overflow_allocator() const { return base_type::get_allocator().get_overflow_allocator(); }
197 };
198 
199 
200 template <size_t nodeCount, bool bEnableOverflow, typename... Ts>
203 {
204  a.swap(b);
205 }
206 
207 
208 } // namespace eastl
209 
210 #endif // EASTL_TUPLEVECTOR_H
Definition: allocator.h:52
Definition: fixed_tuple_vector.h:41
Definition: fixed_pool.h:1329
Definition: iterator.h:411
Definition: initializer_list.h:38
EA Standard Template Library.
Definition: algorithm.h:288