1 /////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) Electronic Arts Inc. All rights reserved.
3 /////////////////////////////////////////////////////////////////////////////
4
5
6 #include "EASTLTest.h"
7 #include <EASTL/memory.h>
8 #include <EASTL/utility.h>
9 #include <EASTL/vector.h>
10 #include <EAStdC/EAMemory.h>
11 #include <EAStdC/EAAlignment.h>
12
13
14 // Regression for user reported operator new problem (12/8/2009):
15 class AssetHandler
16 {
17 public:
operator new(size_t size,const char *,unsigned int)18 inline static void* operator new(size_t size, const char* /*text*/, unsigned int /*flags*/)
19 {
20 return ::operator new(size);
21 }
operator delete(void * p)22 inline static void operator delete(void* p)
23 {
24 return ::operator delete(p);
25 }
26 };
27 typedef eastl::vector<AssetHandler> AssetHandlerArray;
28
29 // Regression test for a default memory fill optimization that defers to memset instead of explicitly
30 // value-initialization each element in a vector individually. This test ensures that the value of the memset is
31 // consistent with an explicitly value-initialized element (namely when the container holds a scalar value that is
32 // memset to zero).
33 template <typename T>
TestValueInitOptimization()34 int TestValueInitOptimization()
35 {
36 int nErrorCount = 0;
37 const int ELEM_COUNT = 100;
38
39 {
40 eastl::vector<T> v1;
41 eastl::vector<ValueInitOf<T>> v2;
42
43 v1.resize(ELEM_COUNT);
44 v2.resize(ELEM_COUNT);
45
46 for (int i = 0; i < ELEM_COUNT; i++)
47 { EATEST_VERIFY(v1[i] == v2[i].get()); }
48 }
49
50 {
51 eastl::vector<T> v1(ELEM_COUNT);
52 eastl::vector<ValueInitOf<T>> v2(ELEM_COUNT);
53
54 for (int i = 0; i < ELEM_COUNT; i++)
55 { EATEST_VERIFY(v1[i] == v2[i].get()); }
56 }
57
58 EATEST_VERIFY(nErrorCount == 0);
59 return nErrorCount;
60 }
61
62
63 // LCTestObject
64 //
65 // Helps test the late_constructed utility.
66 // Has an unusual alignment so we can test that aspect of late_constructed.
67 //
68 struct EA_ALIGN(64) LCTestObject
69 {
70 int mX; //
71 static int64_t sTOCount; // Count of all current existing objects.
72 static int64_t sTOCtorCount; // Count of times any ctor was called.
73 static int64_t sTODtorCount; // Count of times dtor was called.
74
LCTestObjectLCTestObject75 explicit LCTestObject(int x = 0)
76 : mX(x)
77 {
78 ++sTOCount;
79 ++sTOCtorCount;
80 }
81
LCTestObjectLCTestObject82 LCTestObject(int x0, int x1, int x2)
83 : mX(x0 + x1 + x2)
84 {
85 ++sTOCount;
86 ++sTOCtorCount;
87 }
88
LCTestObjectLCTestObject89 LCTestObject(const LCTestObject& testObject)
90 : mX(testObject.mX)
91 {
92 ++sTOCount;
93 ++sTOCtorCount;
94 }
95
96 #if !defined(EA_COMPILER_NO_RVALUE_REFERENCES)
LCTestObjectLCTestObject97 LCTestObject(TestObject&& testObject)
98 : mX(testObject.mX)
99 {
100 ++sTOCount;
101 ++sTOCtorCount;
102 }
103 #endif
104
operator =LCTestObject105 LCTestObject& operator=(const LCTestObject& testObject)
106 {
107 mX = testObject.mX;
108 return *this;
109 }
110
111 #if !defined(EA_COMPILER_NO_RVALUE_REFERENCES)
operator =LCTestObject112 LCTestObject& operator=(LCTestObject&& testObject)
113 {
114 eastl::swap(mX, testObject.mX);
115 return *this;
116 }
117 #endif
118
~LCTestObjectLCTestObject119 ~LCTestObject()
120 {
121 --sTOCount;
122 ++sTODtorCount;
123 }
124 };
125
126 int64_t LCTestObject::sTOCount = 0;
127 int64_t LCTestObject::sTOCtorCount = 0;
128 int64_t LCTestObject::sTODtorCount = 0;
129
130
131 eastl::late_constructed<LCTestObject, true> gLCTestObjectTrue;
132 eastl::late_constructed<LCTestObject, false> gLCTestObjectFalse;
133
134
135 ///////////////////////////////////////////////////////////////////////////////
136 // TestMemory
137 //
TestMemory()138 int TestMemory()
139 {
140 using namespace eastl;
141
142 int nErrorCount = 0;
143
144 TestObject::Reset();
145
146 {
147 // get_temporary_buffer(ptrdiff_t n, size_t alignment, size_t alignmentOffset, char* pName);
148
149 pair<int*, ptrdiff_t> pr1 = get_temporary_buffer<int>(100, 1, 0, EASTL_NAME_VAL("Temp int array"));
150 memset(pr1.first, 0, 100 * sizeof(int));
151 return_temporary_buffer(pr1.first);
152
153 // Note that
154 pair<TestObject*, ptrdiff_t> pr2 = get_temporary_buffer<TestObject>(300);
155 memset(pr2.first, 0, 300 * sizeof(TestObject));
156 return_temporary_buffer(pr2.first, pr2.second);
157 }
158
159 EATEST_VERIFY(TestObject::IsClear());
160 TestObject::Reset();
161
162
163 {
164 LCTestObject* pLCTO;
165
166 // Verify alignment requirements.
167 // We don't verify that gLCTestObjectTrue.get() is aligned for all platforms because some platforms can't do that with global memory.
168 static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::value_type>::value == 64, "late_constructed alignment failure.");
169 static_assert(eastl::alignment_of<typename late_constructed<LCTestObject>::storage_type>::value == 64, "late_constructed alignment failure.");
170 static_assert(eastl::alignment_of<late_constructed<LCTestObject> >::value >= 64, "late_constructed alignment failure.");
171
172
173 // late_constructed / gLCTestObjectTrue
174 EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
175 EATEST_VERIFY(!gLCTestObjectTrue.is_constructed());
176
177 pLCTO = gLCTestObjectTrue.get(); // This will auto-construct LCTestObject.
178 EATEST_VERIFY(pLCTO != NULL);
179 EATEST_VERIFY(gLCTestObjectTrue.is_constructed());
180 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
181
182 gLCTestObjectTrue->mX = 17;
183 EATEST_VERIFY(gLCTestObjectTrue->mX == 17);
184 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
185
186 gLCTestObjectTrue.destruct();
187 EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
188 EATEST_VERIFY(!gLCTestObjectTrue.is_constructed());
189
190 gLCTestObjectTrue->mX = 18;
191 EATEST_VERIFY(gLCTestObjectTrue->mX == 18);
192 EATEST_VERIFY(gLCTestObjectTrue.is_constructed());
193 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
194
195 gLCTestObjectTrue.destruct();
196 (*gLCTestObjectTrue).mX = 19;
197 EATEST_VERIFY(gLCTestObjectTrue->mX == 19);
198 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
199
200 gLCTestObjectTrue.destruct();
201 LCTestObject::sTOCount = 0;
202 LCTestObject::sTOCtorCount = 0;
203 LCTestObject::sTODtorCount = 0;
204
205 // late_constructed / gLCTestObjectFalse
206 EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
207 EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
208
209 pLCTO = gLCTestObjectFalse.get(); // This will not auto-construct LCTestObject.
210 EATEST_VERIFY(pLCTO == NULL);
211 EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
212 EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 0) && (LCTestObject::sTODtorCount == 0));
213
214 gLCTestObjectFalse.construct();
215 pLCTO = gLCTestObjectFalse.get();
216 EATEST_VERIFY(pLCTO != NULL);
217 EATEST_VERIFY(gLCTestObjectFalse.is_constructed());
218 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
219
220 gLCTestObjectFalse->mX = 17;
221 EATEST_VERIFY(gLCTestObjectFalse->mX == 17);
222 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 0));
223
224 gLCTestObjectFalse.destruct();
225 EATEST_VERIFY((LCTestObject::sTOCount == 0) && (LCTestObject::sTOCtorCount == 1) && (LCTestObject::sTODtorCount == 1));
226 EATEST_VERIFY(!gLCTestObjectFalse.is_constructed());
227
228 gLCTestObjectFalse.construct(14);
229 EATEST_VERIFY(gLCTestObjectFalse->mX == 14);
230 gLCTestObjectFalse->mX = 18;
231 EATEST_VERIFY(gLCTestObjectFalse->mX == 18);
232 EATEST_VERIFY(gLCTestObjectFalse.is_constructed());
233 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 2) && (LCTestObject::sTODtorCount == 1));
234
235 gLCTestObjectFalse.destruct();
236 gLCTestObjectFalse.construct(10, 20, 30);
237 EATEST_VERIFY(gLCTestObjectFalse->mX == 10+20+30);
238 (*gLCTestObjectFalse).mX = 19;
239 EATEST_VERIFY(gLCTestObjectFalse->mX == 19);
240 EATEST_VERIFY((LCTestObject::sTOCount == 1) && (LCTestObject::sTOCtorCount == 3) && (LCTestObject::sTODtorCount == 2));
241
242 gLCTestObjectFalse.destruct();
243 }
244
245
246 // We use the vector container to supply a RandomAccessIterator.
247 // We use the list container to supply a BidirectionalIterator.
248 // We use the slist container to supply a ForwardIterator.
249 // We use our generic_input_iterator adapter to supply an InputIterator.
250
251 // eastl::vector<int> intVector;
252 // eastl::list<int> intList;
253 // eastl::slist<int> intSlist;
254
255 // template <typename ForwardIterator, typename ForwardIteratorDest>
256 // inline ForwardIteratorDest uninitialized_relocate_start(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest)
257
258 // template <typename ForwardIterator, typename ForwardIteratorDest>
259 // inline ForwardIteratorDest uninitialized_relocate_commit(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest)
260
261 // template <typename ForwardIterator, typename ForwardIteratorDest>
262 // inline ForwardIteratorDest uninitialized_relocate_abort(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest)
263
264 // template <typename ForwardIterator, typename ForwardIteratorDest>
265 // inline ForwardIteratorDest uninitialized_relocate(ForwardIterator first, ForwardIterator last, ForwardIteratorDest dest)
266
267 // This test does little more than verify that the code compiles.
268 int* pEnd = eastl::uninitialized_relocate_start<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
269 EATEST_VERIFY(pEnd == NULL);
270
271 pEnd = eastl::uninitialized_relocate_commit<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
272 EATEST_VERIFY(pEnd == NULL);
273
274 pEnd = eastl::uninitialized_relocate_abort<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
275 EATEST_VERIFY(pEnd == NULL);
276
277 pEnd = eastl::uninitialized_relocate<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
278 EATEST_VERIFY(pEnd == NULL);
279
280
281
282 // template <typename InputIterator, typename ForwardIterator>
283 // ForwardIterator uninitialized_copy(InputIterator sourceFirst, InputIterator sourceLast, ForwardIterator destination);
284
285 pEnd = eastl::uninitialized_copy<int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
286 EATEST_VERIFY(pEnd == NULL);
287
288
289
290 // template <typename First, typename Last, typename Result>
291 // Result uninitialized_copy_ptr(First first, Last last, Result result)
292
293 pEnd = eastl::uninitialized_copy_ptr<int*, int*, int*>((int*)NULL, (int*)NULL, (int*)NULL);
294 EATEST_VERIFY(pEnd == NULL);
295
296
297
298 // template <typename ForwardIterator, typename T>
299 // void uninitialized_fill(ForwardIterator first, ForwardIterator last, const T& value)
300
301 eastl::uninitialized_fill<int*, int>((int*)NULL, (int*)NULL, (int)0);
302
303
304
305 // template <typename T>
306 // void uninitialized_fill_ptr(T* first, T* last, const T& value)
307
308 eastl::uninitialized_fill_ptr<int>((int*)NULL, (int*)NULL, (int)0);
309
310
311
312 // template <typename ForwardIterator, typename Count, typename T>
313 // void uninitialized_fill_n(ForwardIterator first, Count n, const T& value)
314
315 eastl::uninitialized_fill_n<int*, int, int>((int*)NULL, (int)0, (int)0);
316
317
318
319 // template <typename T, typename Count>
320 // void uninitialized_fill_n_ptr(T* first, Count n, const T& value)
321
322 eastl::uninitialized_fill_n_ptr<int, int>((int*)NULL, (int)0, (int)0);
323
324
325
326
327 // template <typename InputIterator, typename ForwardIterator, typename T>
328 // void uninitialized_copy_fill(InputIterator first1, InputIterator last1,
329 // ForwardIterator first2, ForwardIterator last2, const T& value)
330
331 eastl::uninitialized_copy_fill<int*, int*, int>((int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL, (int)0);
332
333
334
335 // template <typename ForwardIterator, typename T, typename InputIterator>
336 // ForwardIterator uninitialized_fill_copy(ForwardIterator result, ForwardIterator mid, const T& value, InputIterator first, InputIterator last)
337
338 eastl::uninitialized_fill_copy<int*, int, int*>((int*)NULL, (int*)NULL, (int)0, (int*)NULL, (int*)NULL);
339
340
341
342 // template <typename InputIterator1, typename InputIterator2, typename ForwardIterator>
343 // ForwardIterator uninitialized_copy_copy(InputIterator1 first1, InputIterator1 last1,
344 // InputIterator2 first2, InputIterator2 last2,
345 // ForwardIterator result)
346
347 eastl::uninitialized_copy_copy<int*, int*, int*>((int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL, (int*)NULL);
348
349 // uninitialized_default_construct
350 {
351 TestObject::Reset();
352 char testCharArray[sizeof(TestObject) * 10];
353 TestObject* pTestMemory = (TestObject*)(testCharArray);
354
355 eastl::uninitialized_default_construct(pTestMemory, pTestMemory + 10);
356 EATEST_VERIFY(TestObject::sTODefaultCtorCount == 10);
357 }
358
359 // uninitialized_default_construct_n
360 {
361 TestObject::Reset();
362 char testCharArray[sizeof(TestObject) * 10];
363 TestObject* pTestMemory = (TestObject*)(testCharArray);
364
365 auto endIter = eastl::uninitialized_default_construct_n(pTestMemory, 5);
366 EATEST_VERIFY(TestObject::sTODefaultCtorCount == 5);
367 EATEST_VERIFY(endIter == (pTestMemory + 5));
368 }
369
370 // uninitialized_value_construct
371 {
372 TestObject::Reset();
373 char testCharArray[sizeof(TestObject) * 10];
374 TestObject* pTestMemory = (TestObject*)(testCharArray);
375
376 eastl::uninitialized_value_construct(pTestMemory, pTestMemory + 10);
377 EATEST_VERIFY(TestObject::sTODefaultCtorCount == 10);
378 }
379
380 // uninitialized_value_construct_n
381 {
382 TestObject::Reset();
383 char testCharArray[sizeof(TestObject) * 10];
384 TestObject* pTestMemory = (TestObject*)(testCharArray);
385
386 auto endIter = eastl::uninitialized_value_construct_n(pTestMemory, 5);
387 EATEST_VERIFY(TestObject::sTODefaultCtorCount == 5);
388 EATEST_VERIFY(endIter == (pTestMemory + 5));
389 }
390
391 // Verify that uninitialized_value_construct does not do any additional initialization besides zero-initialization.
392 //
393 /// Value-Initialization:
394 // If T is a class, the object is default-initialized (after being zero-initialized if T's default
395 // constructor is not user-provided/deleted); otherwise, the object is zero-initialized.
396 {
397 struct foo
398 {
399 // foo() = default; // intentionally removed to force zero-initialization behavior
400 char mV;
401 };
402
403 static const int ARRAY_SIZE_IN_BYTES = sizeof(foo) * 10;
404
405 char testCharArray[ARRAY_SIZE_IN_BYTES];
406 EA::StdC::Memfill8(testCharArray, 42, ARRAY_SIZE_IN_BYTES);
407 foo* pTestMemory = (foo*)testCharArray;
408
409 eastl::uninitialized_value_construct(pTestMemory, pTestMemory + 10);
410
411 for (int i = 0; i < 10; i++)
412 {
413 EATEST_VERIFY(pTestMemory[i].mV == 0); // verify that memory is zero-initialized
414 }
415 }
416
417 // Verify that uninitialized_default_construct does not do any additional initialization besides the calling of a empty
418 // constructor.
419 //
420 // Default-initialization:
421 // If T is a class, the default constructor is called; otherwise, no initialization is done, resulting in
422 // indeterminate values.
423 {
424 struct foo
425 {
426 foo() {} // default ctor intentionally a no-op
427 char mV;
428 };
429
430 static const int ARRAY_SIZE_IN_BYTES = sizeof(foo) * 10;
431
432 char testCharArray[ARRAY_SIZE_IN_BYTES];
433 EA::StdC::Memfill8(testCharArray, 42, ARRAY_SIZE_IN_BYTES);
434 foo* pTestMemory = (foo*)testCharArray;
435
436 eastl::uninitialized_default_construct(pTestMemory, pTestMemory + 10);
437
438 for (int i = 0; i < 10; i++)
439 {
440 EATEST_VERIFY(pTestMemory[i].mV == 42); // verify original memset value is intact
441 }
442 }
443
444 // template <typename T>
445 // void destruct(T* p)
446 {
447 TestObject::Reset();
448 uint64_t testObjectMemory[((sizeof(TestObject) / sizeof(uint64_t)) + 1) * 2];
449
450 TestObject* pTestObject = new(testObjectMemory) TestObject;
451 destruct(pTestObject);
452 EATEST_VERIFY(TestObject::IsClear());
453 }
454
455 // template <typename T>
456 // void destroy_at(T* p)
457 {
458 TestObject::Reset();
459 uint64_t testObjectMemory[((sizeof(TestObject) / sizeof(uint64_t)) + 1) * 2];
460 TestObject* pTestObject = new(testObjectMemory) TestObject;
461 destroy_at(pTestObject);
462
463 EATEST_VERIFY(TestObject::IsClear());
464 }
465
466
467 // template <typename ForwardIterator>
468 // void destruct(ForwardIterator first, ForwardIterator last)
469 {
470 TestObject::Reset();
471 char testObjectMemory[sizeof(TestObject) * 3];
472 TestObject* pTestObject = new(testObjectMemory) TestObject[2];
473 destruct(pTestObject, pTestObject + 2);
474
475 EATEST_VERIFY(TestObject::IsClear());
476 }
477
478 // template <typename ForwardIterator>
479 // void destroy(ForwardIterator first, ForwardIterator last)
480 {
481 TestObject::Reset();
482 char testObjectMemory[sizeof(TestObject) * 3];
483 TestObject* pTestObject = new(testObjectMemory) TestObject[2];
484 destroy(pTestObject, pTestObject + 2);
485
486 EATEST_VERIFY(TestObject::IsClear());
487 }
488
489 // template <typename ForwardIterator, typename Size>
490 // void destroy_n(ForwardIterator first, Size n)
491 {
492 TestObject::Reset();
493 char testObjectMemory[sizeof(TestObject) * 3];
494 TestObject* pTestObject = new (testObjectMemory) TestObject[2];
495
496 destroy_n(pTestObject, 1); // destroy TestObject[0]
497 destroy_n(pTestObject + 1, 1); // destroy TestObject[1]
498
499 EATEST_VERIFY(TestObject::IsClear());
500 }
501
502
503 {
504 // Regression for user reported operator new problem (12/8/2009):
505 eastl::vector<AssetHandler> ahArray;
506 ahArray.push_back(AssetHandler());
507 }
508
509
510 // void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
511 // void* align_advance(size_t alignment, size_t size, void*& ptr, size_t& space);
512 {
513 const size_t kBufferSize = 256;
514 char buffer[kBufferSize * 2];
515 size_t space = sizeof(buffer);
516 void* ptr = buffer;
517 void* ptrSaved;
518 void* ptrAligned;
519 size_t i;
520
521 // First get 256 bytes of space aligned to 256.
522 // It's a coincidence that we are using eastl::align to set up a buffer for testing eastl::align below.
523 ptrSaved = eastl::align(256, 256, ptr, space);
524
525 // At this point we have 256 bytes of memory aligned on 256 bytes, within buffer.
526 // We test allocating multiple blocks from this space at various alignments values.
527 // We also test that the function sets ptr to the next available location after the
528 // returned allocated block.
529 EA::StdC::Memset8(buffer, 0x00, sizeof(buffer));
530 EATEST_VERIFY(EA::StdC::IsAligned(ptr, 256));
531
532 // align test
533 // Try a number of allocation sizes.
534 for(size_t a = 1; a < 64; a *= 2)
535 {
536 // Do multiple sequental allocations from the storage.
537 for(i = 0, space = 256, ptr = ptrSaved; i < kBufferSize; i += a)
538 {
539 ptrAligned = eastl::align(a, a, ptr, space);
540
541 EATEST_VERIFY((uintptr_t)ptrAligned == ((uintptr_t)ptrSaved + i));
542 EATEST_VERIFY(ptr == ptrAligned);
543 EATEST_VERIFY(space == (kBufferSize - i));
544 EATEST_VERIFY(EA::StdC::IsAligned(ptrAligned, a));
545 EATEST_VERIFY(EA::StdC::Memcheck8(ptrAligned, 0x00, a) == NULL);
546
547 ptr = (char*)ptr + a;
548 space -= a;
549 memset(ptrAligned, 0xff, a); // Do this so that next time around we can verify this memory isn't returned.
550 }
551
552 EA::StdC::Memset8(buffer, 0x00, sizeof(buffer));
553 }
554
555 // align_advance test (similar to but not identical to the align test)
556 // Try a number of allocation sizes.
557 for(size_t a = 1; a < 64; a *= 2)
558 {
559 // Do multiple sequental allocations from the storage.
560 for(i = 0, space = 256, ptr = ptrSaved; i < kBufferSize; i += a)
561 {
562 ptrAligned = eastl::align_advance(a, a, ptr, space, &ptr, &space);
563
564 EATEST_VERIFY((uintptr_t)ptrAligned == ((uintptr_t)ptrSaved + i));
565 EATEST_VERIFY((uintptr_t)ptr == (uintptr_t)ptrAligned + a);
566 EATEST_VERIFY(space == (kBufferSize - i) - a);
567 EATEST_VERIFY(EA::StdC::IsAligned(ptrAligned, a));
568 EATEST_VERIFY(EA::StdC::Memcheck8(ptrAligned, 0x00, a) == NULL);
569
570 memset(ptrAligned, 0xff, a); // Do this so that next time around we can verify this memory isn't returned.
571 }
572
573 EA::StdC::Memset8(buffer, 0x00, sizeof(buffer));
574 }
575 }
576
577 {
578 // Test that align handles integral overflow correctly and returns NULL.
579 void* ptr;
580 void* ptrSaved;
581 size_t space;
582 void* pResult;
583
584 space = 64;
585 ptr = 0;
586 ptr = (char*)ptr - space;
587 ptrSaved = ptr;
588 pResult = eastl::align(1, space + 1, ptr, space); // Possible alignment, impossible size due to wraparound.
589 EATEST_VERIFY((pResult == NULL) && (ptr == ptrSaved));
590
591 space = 64;
592 ptr = 0;
593 ptr = (char*)ptr - space;
594 ptrSaved = ptr;
595 pResult = eastl::align(space * 2, 32, ptr, space); // Impossible alignment due to wraparound, possible size.
596 EATEST_VERIFY((pResult == NULL) && (ptr == ptrSaved));
597 }
598
599 {
600 nErrorCount += TestValueInitOptimization<int>();
601 nErrorCount += TestValueInitOptimization<char>();
602 nErrorCount += TestValueInitOptimization<short>();
603 nErrorCount += TestValueInitOptimization<float>();
604 nErrorCount += TestValueInitOptimization<double>();
605 nErrorCount += TestValueInitOptimization<void*>();
606 }
607
608 EATEST_VERIFY(nErrorCount == 0);
609 return nErrorCount;
610 }
611
612
613
614
615
616
617
618
619
620
621
622