1 /**
2     Implementation of dynamic array `Vector` (similar to c++ `std::vector` and `folly::small_vector`).
3 
4     License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
5     Authors:   Adam Búš
6 */
7 module btl.vector;
8 
9 import std.traits : Unqual, Unconst, isSomeChar, isSomeString, CopyTypeQualifiers;
10 import std.meta : AliasSeq;
11 import std.traits : Select;
12 
13 import btl.traits.common;
14 import btl.traits.range;
15 import btl.lifetime;
16 
17 import btl.internal.traits;
18 import btl.internal.allocator;
19 import btl.internal.gc;
20 
21 import btl.vector.storage;
22 
23 
24 /**
25     Type used in forward constructors.
26 */
27 alias Forward = btl.traits.common.Forward;
28 
29 
30 /**
31     Default allcoator for `Vector`.
32 */
33 public alias DefaultAllocator = Mallocator;
34 
35 
36 /**
37     True if `T` is a `Vector` or implicitly converts to one, otherwise false.
38 */
39 template isVector(T...)
40 if(T.length == 1){
41     enum bool isVector = is(Unqual!(T[0]) == Vector!Args, Args...);
42 }
43 
44 
45 /**
46     `Vector`s are sequence containers representing arrays that can change in size.
47 
48     Just like arrays, vectors use contiguous storage locations for their elements, which means that their elements can also be accessed using offsets on regular pointers to its elements, and just as efficiently as in arrays. But unlike arrays, their size can change dynamically, with their storage being handled automatically by the container.
49 
50     Instead, vector containers may allocate some extra storage to accommodate for possible growth, and thus the container may have an actual capacity greater than the storage strictly needed to contain its elements (i.e., its size). Libraries can implement different strategies for growth to balance between memory usage and reallocations, but in any case, reallocations should only happen at logarithmically growing intervals of size so that the insertion of individual elements at the end of the vector can be provided with amortized constant time complexity (see push_back).
51 
52     Therefore, compared to arrays, vectors consume more memory in exchange for the ability to manage storage and grow dynamically in an efficient way.
53 
54     `Vector` can have preallocated (stack) space for `N` elements.
55 
56     Template parameters:
57 
58         `_Type` = element type.
59 
60         `N` Number of preallocated space for elements.
61 
62         `_Allocator` Type of the allocator object used to define the storage allocation model. By default `DefaultAllocator` is used.
63 
64 
65     @safe:
66 
67         * Inserting element to `Vector` pointer is @safe if constructor of element is @safe (assumption is that constructor doesn't leak `this` pointer).
68 
69         * `Vector` assume that deallocation with custom allocator is @safe if allocation is @safe even if method `deallcoate` is @system.
70 
71         * Methods returning reference/pointer/slice (`front()`, `back()`, `ptr()`, `elements()`, `opSlice()`, ...) to vector elements are all @system because increasing capacity of vector can realocate all elements to new memory location and invalidate external references to old location.
72 
73 
74     `scope` and -dip1000:
75 
76         * `Vector` assume that managed object have global lifetime (scope can be ignored).
77 
78         * Functions for inserting elements to vector have  non `scope` parameters (global lifetime).
79 */
80 template Vector(
81     _Type,
82     size_t N = 0,
83     _Allocator = DefaultAllocator,
84     bool _supportGC = shouldAddGCRange!_Type
85 ){
86 
87     import core.lifetime : emplace, forward, move;
88     import std.range : empty, front, popFront, ElementEncodingType, hasLength;
89     import std.traits : Unqual, hasElaborateDestructor, hasIndirections, isDynamicArray;
90 
91     alias Storage = .Storage!(_Type, N, _allowHeap);
92 
93     enum bool _hasStatelessAllocator = isStatelessAllocator!_Allocator;
94     enum bool _allowHeap = !is(immutable _Allocator == immutable void);
95 
96     struct Vector{
97 
98         /**
99             True if allocator doesn't have state.
100         */
101         public alias hasStatelessAllocator = _hasStatelessAllocator;
102 
103 
104 
105         /**
106             Type of elements.
107         */
108         public alias ElementType = _Type;
109 
110 
111 
112         /**
113             Type of reference to elements.
114         */
115         public alias ElementReferenceType = ElementReferenceTypeImpl!_Type;
116 
117 
118 
119         /**
120             Type of the allocator object used to define the storage allocation model. By default `DefaultAllocator` is used.
121         */
122         public alias AllocatorType = _Allocator;
123 
124 
125 
126         /**
127         */
128         public alias supportGC = _supportGC;
129 
130 
131 
132         /**
133             Allow heap (`false` only if `Allcoator` is void)
134         */
135         public alias allowHeap = _allowHeap;
136 
137 
138 
139         /**
140             Maximal capacity of vector, in terms of number of elements.
141         */
142         public alias maximalCapacity = Storage.maximalCapacity;
143 
144 
145 
146         /**
147             Minimal capacity of vector, in terms of number of elements.
148 
149             Examples:
150                 --------------------
151                 Vector!(int, 10) vec;
152                 assert(vec.capacity == typeof(vec).minimalCapacity);
153                 assert(vec.capacity == 10);
154                 --------------------
155         */
156         public alias minimalCapacity = Storage.minimalCapacity;
157 
158 
159 
160         /**
161             Returns copy of allocator.
162         */
163         public @property CopyTypeQualifiers!(This, AllocatorType) allocator(this This)()scope{
164             static if(allowHeap)
165                 return *(()@trusted => &this._allocator )();
166             else
167                 return;
168         }
169 
170 
171 
172         /**
173             Returns whether the vector is empty (i.e. whether its length is 0).
174 
175             Examples:
176                 --------------------
177                 Vector!(int, 10) vec;
178                 assert(vec.empty);
179 
180                 vec.append(42);
181                 assert(!vec.empty);
182                 --------------------
183         */
184         public @property bool empty()const scope pure nothrow @safe @nogc{
185             return (this.length == 0);
186         }
187 
188 
189 
190         /**
191             Returns whether the vector is full (i.e. whether its length is equal to maximalCapacity).
192 
193             Examples:
194                 --------------------
195                 Vector!(int, 4, void) vec;  //FixedVector
196                 assert(vec.empty);
197                 assert(vec.maximalCapacity == vec.minimalCapacity);
198 
199                 vec.resize(vec.maximalCapacity);
200                 assert(vec.full);
201                 --------------------
202         */
203         public @property bool full()const scope pure nothrow @safe @nogc{
204             return (this.length == maximalCapacity);
205         }
206 
207 
208 
209         /**
210             Returns the length of the vector, in terms of number of elements.
211 
212             This is the number of actual elements that conform the contents of the `Vector`, which is not necessarily equal to its storage capacity.
213 
214             Examples:
215                 --------------------
216                 Vector!(int, 10) vec = null;
217                 assert(vec.length == 0);
218 
219                 vec.append(42);
220                 assert(vec.length == 1);
221 
222                 vec.append(123);
223                 assert(vec.length == 2);
224 
225                 vec.clear();
226                 assert(vec.length == 0);
227                 --------------------
228         */
229         public @property size_t length()const scope pure nothrow @safe @nogc{
230             return this.storage.length;
231         }
232 
233 
234 
235         /**
236             Returns the size of the storage space currently allocated for the `Vector`.
237 
238             This capacity is not necessarily equal to the vector length. It can be equal or greater, with the extra space allowing the object to optimize its operations when new elements are added to the `Vector`.
239 
240             Notice that this capacity does not suppose a limit on the length of the `Vector`. When this capacity is exhausted and more is needed, it is automatically expanded by the object (reallocating it storage space).
241 
242             The capacity of a `Vector` can be altered any time the object is modified, even if this modification implies a reduction in size.
243 
244             The capacity of a `Vector` can be explicitly altered by calling member `reserve`.
245 
246             Examples:
247                 --------------------
248                 Vector!(int, 10) vec;
249                 assert(vec.capacity == typeof(vec).minimalCapacity);
250 
251                 vec.reserve(vec.capacity * 2);
252                 assert(vec.capacity > typeof(vec).minimalCapacity);
253                 --------------------
254         */
255         public @property size_t capacity()const scope pure nothrow @trusted @nogc{
256             return this.storage.capacity;
257         }
258 
259 
260 
261         /**
262             Return pointer to the first element.
263 
264             The pointer  returned may be invalidated by further calls to other member functions that modify the object.
265 
266             Examples:
267                 --------------------
268                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
269 
270                 assert(vec.ptr[0 .. 3] == [1, 2, 3]);
271                 --------------------
272         */
273         public @property inout(ElementType)* ptr()inout return pure nothrow @system @nogc{
274             return this.storage.ptr;
275         }
276 
277 
278 
279         /**
280         */
281         public @property inout(ElementType)* begin()inout return pure nothrow @system @nogc{
282             return this.ptr;
283         }
284 
285 
286 
287         /**
288         */
289         public @property const(ElementType)* cbegin()const return pure nothrow @system @nogc{
290             return this.ptr;
291         }
292 
293 
294 
295         /**
296         */
297         public @property inout(ElementType)* end()inout return pure nothrow @system @nogc{
298             return (this.ptr + this.length);
299         }
300 
301 
302 
303         /**
304         */
305         public @property const(ElementType)* cend()const return pure nothrow @system @nogc{
306             return (this.ptr + this.length);
307         }
308 
309 
310 
311         /**
312             Return slice of all elements (same as `opSlice()`).
313 
314             The slice returned may be invalidated by further calls to other member functions that modify the object.
315 
316             Examples:
317                 --------------------
318                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
319 
320                 int[] slice = vec.elements;
321                 assert(slice.length == vec.length);
322                 assert(slice.ptr is vec.ptr);
323 
324                 vec.reserve(vec.capacity * 2);
325                 assert(slice.length == vec.length);
326                 // slice contains dangling pointer!
327                 --------------------
328         */
329         public @property inout(ElementType)[] elements()inout return pure nothrow @system @nogc{
330             return this.storage.elements;
331         }
332 
333 
334 
335         /**
336             Return `true` if vector is small (capacity == minimalCapacity)
337         */
338         public @property bool small()const scope pure nothrow @safe @nogc{
339             return !this.storage.external;
340         }
341 
342 
343 
344         /**
345             Destroys the `Vector` object.
346 
347             This deallocates all the storage capacity allocated by the `Vector` using its allocator.
348         */
349         public ~this()scope{
350             this._release_impl();
351         }
352 
353 
354 
355         /**
356             Constructs a empty `Vector` with allocator `a`.
357 
358             Examples:
359                 --------------------
360                 {
361                     Vector!(int, 6) vec = DefaultAllocator.init;
362                     assert(vec.empty);
363                 }
364                 --------------------
365 
366         */
367         static if(allowHeap)
368         public this(AllocatorType a)scope pure nothrow @safe @nogc{
369             static if(!hasStatelessAllocator)
370                 this._allocator = forward!a;
371         }
372 
373 
374 
375         /**
376             Constructs a empty `Vector`
377 
378             Examples:
379                 --------------------
380                 {
381                     Vector!(int, 6) vec = null;
382                     assert(vec.empty);
383                 }
384                 --------------------
385 
386         */
387         public this(typeof(null) nil, Forward = Forward.init)scope pure nothrow @safe @nogc{
388         }
389 
390 
391 
392         /**
393             Constructs a `Vector` object from other vector.
394 
395             Parameters:
396                 `rhs` other vector of `Vector` type.
397 
398                 `allocator` optional allocator parameter.
399 
400             Examples:
401                 --------------------
402                 {
403                     Vector!(int, 6) vec = null;
404                     assert(vec.empty);
405                 }
406 
407                 {
408                     Vector!(int, 6) vec = Vector!(int, 6).build(1, 2);
409                     assert(vec == [1, 2]);
410                 }
411 
412                 {
413                     auto tmp = Vector!(int, 6).build(1, 2);
414                     Vector!(int, 6) vec = tmp;
415                     assert(vec == [1, 2]);
416                 }
417 
418 
419                 {
420                     Vector!(int, 6) vec = Vector!(int, 4).build(1, 2);
421                     assert(vec == [1, 2]);
422                 }
423 
424                 {
425                     auto tmp = Vector!(int, 4).build(1, 2);
426                     Vector!(int, 6) vec = tmp;
427                     assert(vec == [1, 2]);
428                 }
429 
430                 {
431                     int[3] tmp = [1, 2, 3];
432                     Vector!(int, 6) vec = tmp[];
433                     assert(vec == [1, 2, 3]);
434                 }
435 
436                 {
437                     struct Range{
438                         int i;
439 
440                         bool empty()(){return i == 0;}
441                         int front()(){return i;}
442                         void popFront()(){i -= 1;}
443                         //size_t length(); //no length
444                     }
445 
446                     Vector!(int, 6) vec = Range(3);
447                     assert(vec == [3, 2, 1]);
448                 }
449                 --------------------
450         */
451         public this(Rhs, this This)(scope auto ref Rhs rhs)scope
452         if(    isVector!Rhs
453             && isConstructable!(Rhs, This)
454             && (isRef!Rhs || !is(immutable This == immutable Rhs))
455         ){
456             this(forward!rhs, Forward.init);
457         }
458 
459 
460 
461         /**
462             Forward constructor.
463         */
464         public this(Rhs, this This)(scope auto ref Rhs rhs, Forward)scope
465         if(isVector!Rhs && isConstructable!(Rhs, This)){
466 
467             //move:
468             static if(isMoveConstructable!(rhs, This)){
469                 if(rhs.storage.external){
470                     //heap -> heap:
471                     if(minimalCapacity <= Rhs.minimalCapacity || minimalCapacity < rhs.length){
472                         static if(!hasStatelessAllocator)
473                             this._allocator = move(rhs._allocator);
474 
475                         this.storage.length = rhs.storage.length;
476                         this.storage.heap = rhs.storage.heap;
477                         rhs.storage.reset();
478 
479                         assert(this.storage.external);
480                     }
481                     //heap -> inline:
482                     else{
483                         assert(minimalCapacity >= rhs.length);
484 
485                         static if(!hasStatelessAllocator)
486                             this._allocator = rhs._allocator;
487 
488                         assert(rhs.length <= minimalCapacity);  //this.reserve(rhs.length);
489 
490                         if(rhs.length){
491                             moveEmplaceRangeImpl!false(
492                                 (()@trusted => this.storage.inline.ptr )(),
493                                 (()@trusted => rhs.storage.heap.ptr )(),
494                                 rhs.length
495                             );
496 
497                             this.storage.length = rhs.storage.length;
498                         }
499 
500                         assert(!this.storage.external);
501                     }
502                 }
503                 else{
504                     static if(!hasStatelessAllocator)
505                         this._allocator = move(rhs._allocator);
506 
507                     //inline -> inline:
508                     if(minimalCapacity >= Rhs.minimalCapacity || minimalCapacity >= rhs.length){
509 
510                         if(rhs.length){
511                             moveEmplaceRangeImpl!false(
512                                 (()@trusted => this.storage.inline.ptr )(),
513                                 (()@trusted => rhs.storage.inline.ptr )(),
514                                 rhs.length
515                             );
516 
517                             this.storage.length = rhs.storage.length;
518                             rhs.storage.reset();
519                         }
520 
521                         assert(!this.storage.external);
522                     }
523                     //inline -> heap
524                     else{
525                         this.reserve(rhs.length);
526                         assert(rhs.length);
527 
528                         moveEmplaceRangeImpl!false(
529                             (()@trusted => this.storage.heap.ptr )(),
530                             (()@trusted => rhs.storage.inline.ptr )(),
531                             rhs.length
532                         );
533 
534                         this.storage.length = rhs.storage.length;
535                         assert(this.storage.external);
536                     }
537                 }
538             }
539             //move elements:
540             else static if(!isRef!rhs && isMoveConstructableElement!(GetElementType!Rhs, ElementType)){
541                 static if(!hasStatelessAllocator)
542                     this._allocator = rhs._allocator;
543 
544                 auto range = rhs.storage.elements;
545                 const size_t new_length = range.length;
546 
547                 this.downsize(new_length);
548                 this.reserve(new_length);
549 
550                 const size_t old_length = this.length;
551 
552                 //move asign elements from range
553                 moveAssignRange(this.storage.elements[0 .. min(old_range, new_range)], range);
554 
555                 //move elements from range
556                 if(old_length < new_length){
557                     moveEmplaceRangeImpl!false(
558                         (()@trusted => this.storage.ptr + old_length)(),
559                         (()@trusted => range.ptr )(),
560                         (new_length - old_length)
561                     );
562                 }
563 
564                 this.length = new_length;
565             }
566             //copy:
567             else{
568                 static if(hasStatelessAllocator){
569                     this(rhs.storage.elements);
570                 }
571                 else{
572                     this(rhs.storage.elements, rhs.allocator);
573                 }
574             }
575         }
576 
577 
578 
579         /**
580             Constructs a `Vector` object from range of elements.
581 
582             Parameters:
583                 `range` input reange of `ElementType` elements.
584 
585                 `allocator` optional allocator parameter.
586 
587             Examples:
588                 --------------------
589                 import std.range : iota;
590                 {
591                     Vector!(int, 6) vec = iota(0, 5);
592                     assert(vec == [0, 1, 2, 3, 4]);
593                 }
594                 --------------------
595         */
596         public this(R, this This)(R range, Forward = Forward.init)scope
597         if(isBtlInputRange!R && is(ElementEncodingType!R : GetElementType!This)){
598             this._init_from_range(forward!range);
599         }
600 
601         /// ditto
602         static if(allowHeap)
603         public this(R, this This)(R range, AllocatorType allcoator)return
604         if(isBtlInputRange!R && is(ElementEncodingType!R : GetElementType!This)){
605             static if(!hasStatelessAllocator)
606                 this._allocator = forward!allcoator;
607 
608             this._init_from_range(forward!range);
609         }
610 
611         private void _init_from_range(R, this This)(R range)scope
612         if(isBtlInputRange!R && is(ElementEncodingType!R : GetElementType!This)){
613             auto self = (()@trusted => (cast(Unqual!This*)&this) )();
614 
615             static if(hasLength!R){
616                 const size_t length = range.length;
617 
618                 self.reserve(length);
619 
620                 {
621                     auto elms = ()@trusted{
622                         return cast(GetElementType!This[])self.ptr[0 .. length];
623                     }();
624 
625                     size_t emplaced = 0;
626                     scope(failure){
627                         self.storage.length = emplaced;
628                     }
629 
630                     emplaceElements(emplaced, elms, forward!range);
631                 }
632 
633                 self.storage.length = length;
634             }
635             else{
636                 this.append(forward!range);
637             }
638         }
639 
640 
641 
642         /**
643             Copy constructors
644         */
645         static foreach(alias From; AliasSeq!(
646             typeof(this),
647             const typeof(this),
648             immutable typeof(this),
649         )){
650 
651             static if(hasCopyConstructor!(From, typeof(this)))
652                 this(scope ref From rhs)scope{this(rhs, Forward.init);}
653             else
654                 @disable this(scope ref From rhs)scope pure nothrow @safe;
655 
656             static if(hasCopyConstructor!(From, const typeof(this)))
657                 this(scope ref From rhs)const scope{this(rhs, Forward.init);}
658             else
659                 @disable this(scope ref From rhs)const scope pure nothrow @safe;
660 
661             static if(hasCopyConstructor!(From, immutable typeof(this)))
662                 this(scope ref From rhs)immutable scope{this(rhs, Forward.init);}
663             else
664                 @disable this(scope ref From rhs)immutable scope pure nothrow @safe;
665 
666             static if(hasCopyConstructor!(From, shared typeof(this)))
667                 this(scope ref From rhs)shared scope{this(rhs, Forward.init);}
668             else
669                 @disable this(scope ref From rhs)shared scope pure nothrow @safe;
670 
671             static if(hasCopyConstructor!(From, const shared typeof(this)))
672                 this(scope ref From rhs)const shared scope{this(rhs, Forward.init);}
673             else
674                 @disable this(scope ref From rhs)const shared scope pure nothrow @safe;
675         }
676 
677 
678 
679         /**
680             Assigns a new value `rhs` to the vector, replacing its current contents.
681 
682             Parameter `rhs` can by type of `null`, `Vector` or input range of ElementType elements.
683 
684             Examples:
685                 --------------------
686                 {
687                     Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
688                     assert(!vec.empty);
689 
690                     vec = null;
691                     assert(vec.empty);
692 
693                     vec = Vector!(int, 42).build(3, 2, 1);
694                     assert(vec == [3, 2, 1]);
695 
696                     vec = Vector!(int, 2).build(4, 2);
697                     assert(vec == [4, 2]);
698                 }
699 
700                 {
701                     int[3] tmp = [1, 2, 3];
702                     Vector!(int, 6) vec = tmp[];
703                     assert(vec == [1, 2, 3]);
704                 }
705 
706                 {
707                     struct Range{
708                         int i;
709 
710                         bool empty()(){return i == 0;}
711                         int front()(){return i;}
712                         void popFront()(){i -= 1;}
713                         //size_t length(); //no length
714                     }
715 
716                     Vector!(int, 6) vec = Range(3);
717                     assert(vec == [3, 2, 1]);
718                 }
719                 --------------------
720         */
721         public void opAssign()(typeof(null) rhs)scope{
722             this.clear();
723         }
724 
725         /// ditto
726         public void opAssign(R)(R range)scope
727         if(isBtlInputRange!R && is(ElementEncodingType!R : ElementType)){
728             static if(hasLength!R){
729                 const size_t new_length = range.length;
730 
731                 this.downsize(new_length);
732                 this.reserve(new_length);
733 
734                 const size_t old_length = this.length;
735 
736                 //asign elements from range
737                 copyAssignRange(this.storage.elements[0 .. min(old_length, range.length)], range);
738 
739                 //emplace elements from range
740                 if(old_length < new_length){
741                     auto elms = this.storage.allocatedElements[old_length .. new_length];
742                     //ElementType[] elms = (()@trusted => this.ptr[old_length .. new_length] )();
743                     size_t emplaced = 0;
744 
745                     scope(failure)
746                         this.storage.length = (old_length + emplaced);
747 
748                     emplaceElements(emplaced, elms, forward!range);
749                 }
750 
751                 this.storage.length = new_length;
752             }
753             else{
754                 const size_t old_length = this.length;
755 
756                 for(size_t i; i < this.length && !range.empty; ++i, range.popFront){
757                     copyEmplaceImpl(this.storage.elements[i], range.front);
758                 }
759 
760                 while(!range.empty){
761                     this.append(range.front);
762                     range.popFront;
763                 }
764 
765             }
766         }
767 
768         /// ditto
769         public void opAssign(Rhs)(scope auto ref Rhs rhs)scope
770         if(isVector!Rhs && isAssignable!(Rhs, typeof(this)) ){
771             ///move:
772             static if(isMoveAssignable!(rhs, typeof(this))){
773 
774                 if(rhs.storage.external){
775                     // heap -> heap
776                     if(minimalCapacity <= Rhs.minimalCapacity || minimalCapacity < rhs.length){
777                         static if(!hasStatelessAllocator)
778                             this._allocator = move(rhs._allocator);
779 
780                         this.release();
781 
782                         this.storage.length = rhs.storage.length;
783                         this.storage.heap = rhs.storage.heap;
784                         rhs.storage.reset();
785                         return;
786                     }
787                 }
788             }
789 
790             static if(!isRef!rhs
791                 && isMoveAssignableElement!(GetElementType!Rhs, ElementType)
792             ){
793                 auto range = rhs.storage.elements;
794                 const size_t new_length = range.length;
795 
796                 this.downsize(new_length);
797                 this.reserve(new_length);
798 
799                 const size_t old_length = this.length;
800 
801 
802                 //move asign elements from range
803                 moveAssignRange(this.storage.elements, range);
804 
805                 //move elements from range
806                 if(old_length < new_length){
807 
808                     moveEmplaceRangeImpl!false(
809                         (()@trusted => this.ptr + old_length)(),
810                         (()@trusted => range.ptr )(),
811                         (new_length - old_length)
812                     );
813                 }
814 
815                 this.storage.length = new_length;
816             }
817             else{
818                 this.opAssign(rhs.storage.elements);
819             }
820 
821 
822         }
823 
824 
825 
826         /**
827             Move the last element of the vector, effectively reducing its length by 1.
828 
829             Return erased element.
830 
831             Examples:
832                 --------------------
833                 Vector!(int, 6) vec = Vector!(int, 6).build(10, 20, 30);
834                 assert(vec.length == 3);
835 
836                 assert(vec.popBack == 30);
837                 assert(vec.length == 2);
838 
839                 assert(vec.popBack == 20);
840                 assert(vec.length == 1);
841 
842                 assert(vec.popBack == 10);
843                 assert(vec.empty);
844 
845                 assert(vec.popBack == int.init);
846                 assert(vec.empty);
847                 --------------------
848         */
849         public auto popBack(T = Unqual!ElementType)()scope nothrow
850         if(is(T == Unqual!ElementType) || is(T == void)){
851             
852             if(this.length == 0){
853                 static if(is(T == void))
854                     return;
855                 else
856                     return ElementType.init;
857             }
858 
859             return _pop_back_impl!T();
860         }
861 
862         /// ditto
863         public auto popBack(T : Unqual!ElementType = Unqual!ElementType)(ElementType def = ElementType.init)scope nothrow{
864             return (this.length == 0)
865                 ? move(def)
866                 : _pop_back_impl!T();
867         }
868 
869         private auto _pop_back_impl(T)()scope nothrow
870         if(is(T == Unqual!ElementType) || is(T == void)){
871             assert(this.length != 0);
872 
873             const size_t new_length = (this.length - 1);
874             this.storage.length = new_length;
875 
876             static if(!is(T == void)){
877                 ElementType* ptr = (()@trusted => this.ptr + new_length )();
878                 ElementType result = move(*ptr);
879 
880                 ///TODO can be destruct ignored for moved element?
881                 ///destructImpl!false(*ptr);   //destroyElement(*ptr);
882 
883                 return move(result);
884             }
885 
886         }
887 
888 
889 
890         /**
891             Move the element at position `pos` out of vector, effectively reducing its length by 1.
892 
893             Return erased element.
894 
895             If `pos` is invalid then return `def` or `ElementType.init`.
896 
897             Examples:
898                 --------------------
899                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5);
900                 assert(vec.length == 5);
901 
902                 assert(vec.pop(0) == 1);
903                 assert(vec == [2, 3, 4, 5]);
904 
905                 assert(vec.pop(3) == 5);
906                 assert(vec == [2, 3, 4]);
907 
908                 assert(vec.pop(1) == 3);
909                 assert(vec == [2, 4]);
910                 --------------------
911         */
912         public ElementType pop()(const size_t pos, ElementType def = ElementType.init)scope nothrow{
913             const size_t old_length = this.length;
914 
915             if(pos >= old_length)
916                 return move(def);
917 
918             const size_t top = (pos + 1);
919 
920             ElementType* elm = (()@trusted => this.ptr + pos )();
921             ElementType result = move(*elm);
922 
923             ///TODO can be destruct ignored for moved element?
924             ///destructImpl!false(*elm);   //destroyElement(*elm);
925 
926             if(top < old_length){
927                 moveEmplaceRangeImpl(
928                     elm,
929                     (()@trusted => elm + 1 )(),
930                     (old_length - top)
931                 );
932             }
933 
934             this.storage.length = (old_length - 1);
935             return move(result);
936         }
937 
938 
939 
940         /**
941             Erases the contents of the `Vector`, which becomes an empty vector (with a length of 0 elements).
942 
943             Doesn't change capacity of vector.
944 
945             Examples:
946                 --------------------
947                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
948 
949                 vec.reserve(vec.capacity * 2);
950                 assert(vec.length == 3);
951 
952                 const size_t cap = vec.capacity;
953                 vec.clear();
954                 assert(vec.capacity == cap);
955                 --------------------
956         */
957         public void clear()()scope nothrow{
958             destructRangeImpl!false(this.storage.elements);
959             this.storage.length = 0;
960         }
961 
962 
963 
964         /**
965             Erases and deallocate the contents of the `Vector`, which becomes an empty vector (with a length of 0 elements).
966 
967             Examples:
968                 --------------------
969                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
970 
971                 vec.reserve(vec.capacity * 2);
972                 assert(vec.length == 3);
973 
974                 const size_t cap = vec.capacity;
975                 vec.clear();
976                 assert(vec.capacity == cap);
977 
978                 vec.release();
979                 assert(vec.capacity < cap);
980                 assert(vec.capacity == typeof(vec).minimalCapacity);
981                 --------------------
982         */
983         public void release()()scope nothrow{
984             this._release_impl();
985             this.storage.reset();
986         }
987 
988         private void _release_impl()scope nothrow{
989             const bool is_external = this.storage.external;
990 
991             destructRangeImpl!false(this.storage.elements);
992 
993             static if(allowHeap)
994                 if(is_external){
995 
996                     static if(minimalCapacity == 0){
997                         const size_t cap = this.storage.heap.capacity;
998                         if(cap == 0)
999                             return;
1000 
1001                     }
1002 
1003                     this._deallocate_heap(this.storage.heap);
1004                 }
1005         }
1006 
1007 
1008 
1009         /**
1010             Returns true if memory referenced by `p` is owned by vector.
1011 
1012             Examples:
1013                 --------------------
1014                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
1015 
1016                 {
1017                     assert(vec.owns(vec.ptr + 3));
1018                     assert(!vec.owns(cast(int*)null));
1019                     assert(!vec.owns(vec.ptr + 100));
1020                 }
1021 
1022                 {
1023                     assert(vec.owns(&vec[$-1]));
1024                     assert(!vec.owns(cast(long*)&vec[$-1]));
1025                 }
1026                 --------------------
1027         */
1028         public bool owns(T)(scope const T* p)scope const pure nothrow @trusted @nogc{
1029             return (cast(const void*)this.ptr <= cast(const void*)p)
1030                 && (cast(const void*)(p + 1) <= cast(const void*)(this.ptr + length));
1031         }
1032 
1033 
1034 
1035         /**
1036             Returns true if element referenced by `p` is owned by vector.
1037             Similar to owns but check if p has right alignment.
1038 
1039             Examples:
1040                 --------------------
1041                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
1042 
1043                 {
1044                     assert(vec.ownsElement(vec.ptr + 3));
1045                     assert(!vec.ownsElement(cast(int*)null));
1046                     assert(!vec.ownsElement(vec.ptr + 100));
1047                 }
1048 
1049                 {
1050                     const int* p = cast(int*)((cast(byte*)vec.ptr) + 1);
1051                     assert(vec.owns(p));
1052                     assert(!vec.ownsElement(p));
1053                 }
1054                 --------------------
1055         */
1056         public bool ownsElement(scope const ElementType* p)scope const pure nothrow @trusted @nogc{
1057             return this.owns(p)
1058                 && (cast(size_t)this.ptr % ElementType.sizeof) == (cast(size_t)p % ElementType.sizeof) ;
1059         }
1060 
1061 
1062 
1063         /**
1064             Requests that the vector capacity be adapted to a planned change in size to a length of up to `n` elements.
1065 
1066             If `n` is greater than the current vector capacity, the function causes the container to increase its capacity to `n` elements (or greater).
1067 
1068             In all other cases, it do nothing.
1069 
1070             This function has no effect on the vector length and cannot alter its content.
1071 
1072             Examples:
1073                 --------------------
1074                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1075                 assert(vec.capacity == typeof(vec).minimalCapacity);
1076 
1077                 const size_t cap = (vec.capacity * 2);
1078                 vec.reserve(cap);
1079                 assert(vec.capacity > typeof(vec).minimalCapacity);
1080                 assert(vec.capacity >= cap);
1081                 --------------------
1082         */
1083         public void reserve()(const size_t n)scope nothrow{
1084 
1085             void _reserve_inline(const size_t n)scope nothrow{
1086                 static if(minimalCapacity > 0)
1087                     assert(!this.storage.external);
1088 
1089                 enum size_t old_capacity = Storage.Inline.capacity;  //(()@trusted => this.storage.inline.capacity )();
1090 
1091                 if(n <= old_capacity)
1092                     return;
1093 
1094                 const size_t new_capacity = _grow_capacity(old_capacity, n);
1095 
1096 
1097                 Storage.Heap heap;   // = this._heap_storage_ptr(); //(()@trusted => &this.storage.heap() )();
1098                 auto inline_elements = (()@trusted => this.storage.inline.elements(this.length) )();
1099 
1100                 this._allocate_heap(heap, new_capacity);
1101 
1102                 moveEmplaceRangeImpl!false(
1103                     (()@trusted => heap.ptr )(),
1104                     (()@trusted => this.storage.inline.ptr )(),
1105                     this.length
1106                 );
1107 
1108                 //this.storage.external = true;
1109                 this.storage.heap = heap;
1110             }
1111 
1112             void _reserve_heap(const size_t n)scope nothrow{
1113                 assert(this.storage.external);
1114 
1115                 const old_capacity = this.storage.heap.capacity;   //(()@trusted => this.storage.heap.capacity )();
1116 
1117                 if(n <= old_capacity)
1118                     return;
1119 
1120                 const new_capacity = _grow_capacity(old_capacity , n);
1121 
1122                 if(minimalCapacity > 0 || old_capacity > 0){
1123                     this._reallocate_heap(this.storage.heap, new_capacity, this.length);
1124                 }
1125                 else{
1126                     this._allocate_heap(this.storage.heap, new_capacity);
1127                 }
1128             }
1129 
1130             return this.storage.external
1131                 ? _reserve_heap(n)
1132                 : _reserve_inline(n);
1133         }
1134 
1135 
1136 
1137         /**
1138             Resizes the vector to a length of `n` elements.
1139 
1140             If `n` is smaller than the current vector length, the current value is shortened to its first `n` character, removing the characters beyond the nth.
1141 
1142             If `n` is greater than the current vector length, the current content is extended by inserting at the end as many elements as needed to reach a size of `n`.
1143 
1144             If `args` are specified, the new elements are emplaced with parameters `args`, otherwise, they are `ElementType.init`.
1145 
1146             Examples:
1147                 --------------------
1148                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1149 
1150                 vec.resize(5, 0);
1151                 assert(vec == [1, 2, 3, 0, 0]);
1152 
1153                 vec.resize(2);
1154                 assert(vec == [1, 2]);
1155                 --------------------
1156         */
1157         public void resize(Args...)(const size_t n, auto ref Args args)scope{
1158             const size_t old_length = this.length;
1159 
1160             if(old_length > n){
1161 
1162                 ElementType[] slice = (()@trusted => this.ptr[n .. old_length] )();
1163                 destructRangeImpl!false(slice);
1164                 this.storage.length = n;
1165             }
1166             else if(old_length < n){
1167                 this.reserve(n);
1168 
1169                 ElementType[] elms = ()@trusted{
1170                     return this.storage.allocatedElements[old_length .. n];
1171                 }();
1172                 size_t emplaced = 0;
1173 
1174                 scope(failure){
1175                     this.storage.length = (old_length + emplaced);
1176                 }
1177 
1178                 emplaceElementsArgs(emplaced, elms, forward!args);
1179 
1180                 this.storage.length = n;
1181             }
1182 
1183         }
1184 
1185 
1186 
1187         /**
1188             Downsizes the vector to a length of `n` elements.
1189 
1190             If `n` is smaller than the current vector length, the current value is shortened to its first `n` character, removing the characters beyond the nth.
1191 
1192             If `n` is greater than the current vector length, then nothing happend.
1193 
1194             Examples:
1195                 --------------------
1196                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1197 
1198                 vec.downsize(5);
1199                 assert(vec == [1, 2, 3]);
1200 
1201                 vec.downsize(2);
1202                 assert(vec == [1, 2]);
1203                 --------------------
1204         */
1205         public void downsize()(const size_t n)scope nothrow{
1206             const size_t old_length = this.length;
1207 
1208             if(old_length > n){
1209 
1210                 ElementType[] slice = (()@trusted => this.ptr[n .. old_length] )();
1211                 destructRangeImpl!false(slice);
1212                 this.storage.length = n;
1213             }
1214         }
1215 
1216 
1217 
1218         /**
1219             Upsize the vector to a length of `n` elements.
1220 
1221             If `n` is smaller than the current vector length, then nothing happend.
1222 
1223             If `n` is greater than the current vector length, the current content is extended by inserting at the end as many elements as needed to reach a size of `n`.
1224 
1225             If `args` are specified, the new elements are emplaced with parameters `args`, otherwise, they are `ElementType.init`.
1226 
1227             Examples:
1228                 --------------------
1229                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1230 
1231                 vec.upsize(5, 0);
1232                 assert(vec == [1, 2, 3, 0, 0]);
1233 
1234                 vec.upsize(2);
1235                 assert(vec == [1, 2, 3, 0, 0]);
1236                 --------------------
1237         */
1238         public void upsize(Args...)(const size_t n, auto ref Args args)scope @safe{
1239             const size_t old_length = this.length;
1240 
1241             if(old_length < n){
1242                 this.reserve(n);
1243 
1244                 ElementType[] elms = ()@trusted{
1245                     return this.storage.allocatedElements[old_length .. n];
1246                 }();
1247 
1248                 size_t emplaced = 0;
1249                 scope(failure){
1250                     this.storage.length = (old_length + emplaced);
1251                 }
1252 
1253                 emplaceElementsArgs(emplaced, elms, forward!args);
1254                 this.storage.length = n;
1255             }
1256         }
1257 
1258 
1259 
1260         /**
1261             Requests the `Vector` to reduce its capacity to fit its length.
1262 
1263             The request is non-binding.
1264 
1265             This function has no effect on the vector length and cannot alter its content.
1266 
1267             Examples:
1268                 --------------------
1269                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1270 
1271                 assert(vec.capacity == typeof(vec).minimalCapacity);
1272 
1273                 vec.reserve(vec.capacity * 2);
1274                 assert(vec.capacity > typeof(vec).minimalCapacity);
1275 
1276                 vec.shrinkToFit();
1277                 assert(vec.capacity == typeof(vec).minimalCapacity);
1278                 --------------------
1279         */
1280         public void shrinkToFit(const bool reallocate = true)scope{
1281             if(!this.storage.external)
1282                 return;
1283 
1284             static if(allowHeap){
1285                 const size_t old_capacity = this.storage.heap.capacity;
1286                 const size_t length = this.length;
1287 
1288                 if(length <= minimalCapacity){
1289                     Storage.Heap hs_data = this.storage.heap;
1290 
1291                     this.storage.external = false;
1292                     assert(this.capacity == minimalCapacity);
1293 
1294                     if(minimalCapacity > 0 && length != 0)
1295                         moveEmplaceRangeImpl!false(
1296                             (()@trusted => this.storage.inline.ptr )(),
1297                             (()@trusted => hs_data.ptr )(),
1298                             length
1299                         );
1300 
1301                     this.storage.external = false;
1302                     assert(this.capacity == minimalCapacity);
1303 
1304                     this._deallocate_heap(hs_data);
1305                 }
1306                 else{
1307                     if(reallocate && length < old_capacity){
1308                         this._reallocate_heap!true(this.storage.heap, length, length);
1309                     }
1310                 }
1311             }
1312             else{
1313                 assert(0, "no impl");
1314             }
1315 
1316         }
1317 
1318 
1319 
1320         /**
1321             Operator `~=` and `+=` is same as append
1322         */
1323         public template opOpAssign(string op)
1324         if(op == "~" || op == "+"){
1325             alias opOpAssign = append;
1326         }
1327 
1328 
1329 
1330         /**
1331             Same as operator `in`
1332 
1333             Examples:
1334                 --------------------
1335                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1336 
1337                 assert(vec.contains(1));
1338                 assert(!vec.contains(42L));
1339                 --------------------
1340         */
1341         public bool contains(Elm)(scope auto ref Elm elm)scope const{
1342             foreach(ref e; this.storage.elements){
1343                 if(e == elm)
1344                     return true;
1345             }
1346 
1347             return false;
1348         }
1349 
1350 
1351 
1352         /**
1353             Operator `in`
1354 
1355 
1356             Examples:
1357                 --------------------
1358                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1359 
1360                 assert(1 in vec);
1361                 assert(42L !in vec);
1362                 --------------------
1363         */
1364         public bool opBinaryRight(string op, Elm)(scope auto ref Elm elm)scope const
1365         if(op == "in"){
1366             return this.contains(forward!elm);
1367         }
1368 
1369 
1370 
1371         /**
1372             Compares the contents of a vector with another vector, range or null.
1373 
1374             Returns `true` if they are equal, `false` otherwise
1375 
1376             Examples:
1377                 --------------------
1378                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1379 
1380                 assert(vec != null);
1381                 assert(null != vec);
1382 
1383                 assert(vec == [1, 2, 3]);
1384                 assert([1, 2, 3] == vec);
1385 
1386                 assert(vec == typeof(vec).build(1, 2, 3));
1387                 assert(typeof(vec).build(1, 2, 3) == vec);
1388 
1389 
1390                 import std.range : only;
1391                 assert(vec == only(1, 2, 3));
1392                 assert(only(1, 2, 3) == vec);
1393                 --------------------
1394         */
1395         public bool opEquals(typeof(null) nil)const scope pure nothrow @safe @nogc{
1396             return this.empty;
1397         }
1398 
1399         /// ditto
1400         public bool opEquals(R)(scope R rhs)const scope nothrow
1401         if(isBtlInputRange!R){
1402             import std.algorithm.comparison : equal;
1403 
1404             return equal(this.storage.elements, forward!rhs);
1405         }
1406 
1407         /// ditto
1408         public bool opEquals(V)(scope const auto ref V rhs)const scope nothrow
1409         if(isVector!V){
1410             import std.algorithm.comparison : equal;
1411 
1412             return equal(this.storage.elements, rhs.storage.elements);
1413         }
1414 
1415 
1416 
1417 
1418         /**
1419             Compares the contents of a vector with another vector or range.
1420 
1421             Examples:
1422                 --------------------
1423                 auto a1 = Vector!(int, 6).build(1, 2, 3);
1424                 auto a2 = Vector!(int, 6).build(1, 2, 3, 4);
1425                 auto b = Vector!(int, 6).build(3, 2, 1);
1426 
1427                 assert(a1 < b);
1428                 assert(a1 < a2);
1429                 assert(a2 < b);
1430                 assert(a1 <= a1);
1431                 --------------------
1432         */
1433         public int opCmp(R)(scope R rhs)const scope nothrow
1434         if(isBtlInputRange!R){
1435             import std.algorithm.comparison : cmp;
1436 
1437             return cmp(this.storage.elements, forward!rhs);
1438         }
1439 
1440         /// ditto
1441         public int opCmp(V)(scope const auto ref V rhs)const scope nothrow
1442         if(isVector!V){
1443             import std.algorithm.comparison : cmp;
1444 
1445             return cmp(this.storage.elements, rhs.storage.elements);
1446         }
1447 
1448 
1449 
1450         /**
1451             Returns a slice [begin .. end]. If the requested slice extends past the end of the vector, the returned slice is invalid.
1452 
1453             The slice returned may be invalidated by further calls to other member functions that modify the object.
1454 
1455             Examples:
1456                 --------------------
1457                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
1458 
1459                 assert(vec[1 .. 4] == [2, 3, 4]);
1460                 assert(vec[1 .. $] == [2, 3, 4, 5, 6]);
1461                 --------------------
1462         */
1463         public inout(ElementType)[] opSlice(bool check = true)(const size_t begin, const size_t end)inout return pure nothrow @system @nogc{
1464             this._bounds_check([begin, end]);
1465 
1466             return this.ptr[begin .. end];
1467 
1468         }
1469 
1470         //
1471         public size_t[2] opSlice(size_t dim : 0)(size_t begin, size_t end)const pure nothrow @safe @nogc{
1472             return [begin, end];
1473         }
1474 
1475 
1476 
1477         /**
1478             Return slice of all elements (same as `Vector.elements`).
1479 
1480             The slice returned may be invalidated by further calls to other member functions that modify the object.
1481 
1482             Examples:
1483                 --------------------
1484                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
1485 
1486                 int[] slice = vec[];
1487                 assert(slice.length == vec.length);
1488                 assert(slice.ptr is vec.ptr);
1489 
1490                 vec.reserve(vec.capacity * 2);
1491                 assert(slice.length == vec.length);
1492                 // slice contains dangling pointer!
1493                 --------------------
1494         */
1495         public inout(ElementType)[] opIndex()inout return pure nothrow @system @nogc{
1496             return this.elements();
1497         }
1498 
1499 
1500 
1501         /**
1502             Returns reference to element at specified location `pos`.
1503 
1504             Examples:
1505                 --------------------
1506                 auto vec = Vector!(int, 10).build(1, 2, 3);
1507 
1508                 assert(vec[1] == 2);
1509                 --------------------
1510         */
1511         public ref inout(ElementType) opIndex(const size_t pos)inout scope pure nothrow @system @nogc{
1512             this._bounds_check(pos);
1513 
1514             return *(this.ptr + pos);
1515         }
1516 
1517 
1518 
1519         /**
1520             Returns reference to element at specified location `pos`.
1521 
1522             Examples:
1523                 --------------------
1524                 auto vec = Vector!(int, 10).build(1, 2, 3);
1525 
1526                 assert(vec.at(1) == 2);
1527                 --------------------
1528         */
1529         public ref inout(ElementType) at(const size_t pos)inout scope pure nothrow @system @nogc{
1530             return this.opIndex(pos);
1531         }
1532 
1533 
1534 
1535         /**
1536             Returns a copy to the element at position `pos`.
1537 
1538             Examples:
1539                 --------------------
1540                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
1541 
1542                 assert(vec.atCopy(3) == 4);
1543                 assert(vec.atCopy(vec.length-1) == 6);
1544                 --------------------
1545         */
1546         public GetElementType!This atCopy(this This)(const size_t pos)scope{
1547             this._bounds_check(pos);
1548 
1549             return *(()@trusted => this.ptr + pos )();
1550         }
1551 
1552 
1553 
1554         /**
1555             Assign value `val` to element at position `index`.
1556 
1557             Examples:
1558                 --------------------
1559                 {
1560                     auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
1561 
1562                     vec[1] = 42;
1563 
1564                     assert(vec == [1, 42, 3, 4, 5]);
1565                 }
1566 
1567                 {
1568                     auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
1569 
1570                     vec[1 .. $-1] = 42;
1571 
1572                     assert(vec == [1, 42, 42, 42, 5]);
1573                 }
1574                 --------------------
1575 
1576         */
1577         public void opIndexAssign(Val)(auto ref Val val, size_t index){
1578             this._bounds_check(index);
1579 
1580             *(()@trusted => (this.ptr + index) )() = forward!val;
1581         }
1582 
1583         /// ditto
1584         public void opIndexAssign(Val)(auto ref Val val, size_t[2] index){
1585             this._bounds_check(index);
1586 
1587             foreach(ref elm; (()@trusted => this.ptr[index[0] .. index[1]] )() )
1588                 elm = val;
1589         }
1590 
1591 
1592 
1593         /**
1594             Assign `op` value `val` to element at position `index`.
1595 
1596             Examples:
1597                 --------------------
1598                 {
1599                     auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
1600 
1601                     vec[1] += 40;
1602 
1603                     assert(vec == [1, 42, 3, 4, 5]);
1604                 }
1605 
1606                 {
1607                     auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
1608 
1609                     vec[1 .. $-1] *= -1;
1610 
1611                     assert(vec == [1, -2, -3, -4, 5]);
1612                 }
1613                 --------------------
1614 
1615         */
1616         public void opIndexOpAssign(string op, Val)(auto ref Val val, size_t index){
1617             this._bounds_check(index);
1618 
1619             ref ElementType elm()@trusted{
1620                 return *(this.ptr + index);
1621             }
1622 
1623             mixin("elm() " ~ op ~ "= forward!val;");
1624         }
1625 
1626         /// ditto
1627         public void opIndexOpAssign(string op, Val)(auto ref Val val, size_t[2] index){
1628             this._bounds_check(index);
1629 
1630             foreach(ref elm; (()@trusted => this.ptr[index[0] .. index[1]] )() )
1631                 mixin("elm " ~ op ~ "= val;");
1632         }
1633 
1634 
1635 
1636         /**
1637             Returns the length of the vector, in terms of number of elements.
1638 
1639             Same as `length()`.
1640         */
1641         public size_t opDollar()const scope pure nothrow @safe @nogc{
1642             return this.length;
1643         }
1644 
1645 
1646 
1647         /**
1648             Swaps the contents of `this` and `rhs`.
1649 
1650             Examples:
1651                 --------------------
1652                 auto a = Vector!(int, 6).build(1, 2, 3);
1653                 auto b = Vector!(int, 6).build(4, 5, 6);
1654 
1655                 a.proxySwap(b);
1656                 assert(a == [4, 5, 6]);
1657                 assert(b == [1, 2, 3]);
1658 
1659                 import std.algorithm.mutation : swap;
1660 
1661                 swap(a, b);
1662                 assert(a == [1, 2, 3]);
1663                 assert(b == [4, 5, 6]);
1664                 --------------------
1665         */
1666         public void proxySwap()(ref scope typeof(this) rhs)scope{
1667             import std.algorithm.mutation : swap;
1668 
1669             static if(minimalCapacity == 0){
1670                 static if(!hasStatelessAllocator)
1671                     swap(this._allocator, rhs._allocator);
1672 
1673                 swap(this.storage.length, rhs.storage.length);
1674                 swap(this.storage.heap, rhs.storage.heap);
1675             }
1676             else{
1677                 //heap <-> heap
1678                 if(this.storage.external && rhs.storage.external){
1679                     static if(!hasStatelessAllocator)
1680                         swap(this._allocator, rhs._allocator);
1681 
1682                     swap(this.storage.length, rhs.storage.length);
1683                     swap(this.storage.heap, rhs.storage.heap);
1684                 }
1685                 //inline <-> inline
1686                 else if(!this.storage.external && !rhs.storage.external){
1687                     auto small = (()@trusted => (this.length < rhs.length) ?  &this : &rhs )();
1688                     auto large = (()@trusted => (this.length < rhs.length) ?  &rhs : &this )();
1689 
1690                     //TODO range swap generalization:
1691                     for(size_t i = 0; i < this.length; ++i)
1692                         swap(
1693                             *(()@trusted => small.storage.inline.ptr + i )(),
1694                             *(()@trusted => large.storage.inline.ptr + i )()
1695                         );
1696 
1697                     moveEmplaceRangeImpl(
1698                         (()@trusted => small.storage.inline.ptr + small.length )(),
1699                         (()@trusted => large.storage.inline.ptr + small.length )(),
1700                         (large.length - small.length)
1701                     );
1702 
1703                     swap(this.storage.length, rhs.storage.length);
1704                 }
1705                 //heap <-> inline || inline <-> heap
1706                 else{
1707                     assert(this.storage.external != rhs.storage.external);
1708 
1709                     auto heap = (()@trusted => this.storage.external ? &this : &rhs )();
1710                     auto inline = (()@trusted => this.storage.external ? &rhs : &this )();
1711 
1712                     //copy heap to tmp:
1713                     Storage.Heap tmp_heap = heap.storage.heap;
1714 
1715                     //copy inline to old heap:
1716                     heap.storage.external = false;
1717                     moveEmplaceRangeImpl(
1718                         (()@trusted => heap.storage.inline.ptr )(),
1719                         (()@trusted => inline.storage.inline.ptr )(),
1720                         inline.storage.length
1721                     );
1722 
1723                     //swap lengths:
1724                     swap(inline.storage.length, heap.storage.length);
1725 
1726                     //copy tmp heap to new heap:
1727                     inline.storage.heap = tmp_heap;
1728 
1729                     assert(!heap.storage.external);
1730                     assert(inline.storage.external);
1731                 }
1732 
1733             }
1734         }
1735 
1736 
1737 
1738         /**
1739             Swaps the contents of `this` and `rhs` only if both are heap allocated.
1740 
1741             Return `true` if swap successed or `false` if not (`this` or `rhs` is non heap allocated).
1742 
1743             Examples:
1744                 --------------------
1745                 auto a = Vector!(int, 3).build(1, 2, 3);
1746                 auto b = Vector!(int, 3).build(6, 7, 8);
1747 
1748                 assert(a.heapSwap(b) == false);
1749                 assert(a == [1, 2, 3]);
1750                 assert(b == [6, 7, 8]);
1751 
1752                 a ~= 4;
1753                 b ~= 9;
1754                 assert(a == [1, 2, 3, 4]);
1755                 assert(b == [6, 7, 8, 9]);
1756 
1757                 assert(a.heapSwap(b) == true);
1758                 assert(a == [6, 7, 8, 9]);
1759                 assert(b == [1, 2, 3, 4]);
1760                 --------------------
1761         */
1762         public bool heapSwap()(ref scope typeof(this) rhs)scope{
1763             import std.algorithm.mutation : swap;
1764 
1765             //heap <-> heap
1766             if((minimalCapacity == 0) || (this.storage.external && rhs.storage.external)){
1767                 static if(!hasStatelessAllocator)
1768                     swap(this._allocator, rhs._allocator);
1769 
1770                 swap(this.storage.length, rhs.storage.length);
1771                 swap(this.storage.heap, rhs.storage.heap);
1772 
1773                 return true;
1774             }
1775             else{
1776                 return false;
1777             }
1778         }
1779 
1780 
1781 
1782         /**
1783             Inserts a new element into the container directly before `pos` or `ptr`.
1784 
1785             Return index of first inserted element.
1786 
1787             Parameters:
1788                 `pos` Insertion point, the new contents are inserted before the element at position `pos`.
1789 
1790                 `ptr` Pointer pointing to the insertion point, the new contents are inserted before the element pointed by ptr.
1791 
1792                 `args` arguments to forward to the constructor of the element
1793 
1794             Examples:
1795                 --------------------
1796                 {
1797                     auto vec = Vector!(int, 6).build(1, 2, 3);
1798 
1799                     vec.emplace(1, 42);
1800                     assert(vec == [1, 42, 2, 3]);
1801 
1802                     vec.emplace(4, 314);
1803                     assert(vec == [1, 42, 2, 3, 314]);
1804 
1805                     vec.emplace(100, -1);
1806                     assert(vec == [1, 42, 2, 3, 314, -1]);
1807                 }
1808 
1809                 {
1810                     auto vec = Vector!(int, 6).build(1, 2, 3);
1811 
1812                     vec.emplace(vec.ptr + 1, 42);
1813                     assert(vec == [1, 42, 2, 3]);
1814 
1815                     vec.emplace(vec.ptr + 4, 314);
1816                     assert(vec == [1, 42, 2, 3, 314]);
1817 
1818                     vec.emplace(vec.ptr + 100, -1);
1819                     assert(vec == [1, 42, 2, 3, 314, -1]);
1820                 }
1821 
1822                 {
1823                     static struct Foo{
1824                         int i;
1825                         string str;
1826                     }
1827 
1828                     auto vec = Vector!(Foo, 6).build(Foo(1, "A"));
1829 
1830                     vec.emplace(1, 2, "B");
1831                     assert(vec == only(Foo(1, "A"), Foo(2, "B")));
1832 
1833                     vec.emplace(0, 42, "X");
1834                     assert(vec == only(Foo(42, "X"), Foo(1, "A"), Foo(2, "B")));
1835                 }
1836                 --------------------
1837         */
1838         public size_t emplace(Args...)(const size_t pos, auto ref Args args)scope{
1839             const size_t old_length = this.length;
1840 
1841             if(old_length <= pos){
1842                 this.emplaceBack(forward!args);
1843                 return old_length;
1844             }
1845 
1846             const size_t new_length = (old_length + 1);
1847 
1848             this.reserve(new_length);
1849 
1850             auto ptr = (()@trusted => this.ptr + pos)();
1851 
1852             moveEmplaceRangeImpl(
1853                 ptr + 1,
1854                 ptr,
1855                 (old_length - pos)  //shift
1856             );
1857 
1858             this.storage.length = new_length;
1859 
1860             emplaceImpl(*ptr, forward!args);
1861 
1862             return pos;
1863         }
1864 
1865         /// ditto
1866         public size_t emplace(Args...)(scope const ElementType* ptr, auto ref Args args)scope{
1867             auto this_ptr = (()@trusted => this.ptr )();
1868 
1869             const size_t pos = (ptr < this_ptr)
1870                 ? 0
1871                 : (ptr - this_ptr);
1872 
1873             return this.emplace(pos, forward!args);
1874         }
1875 
1876 
1877 
1878         /**
1879             Appends a new element to the end of the container. The element is constructed through `emplace`.
1880 
1881             Parameters:
1882                 `args`  arguments to forward to the constructor of the element.
1883 
1884             Examples:
1885                 --------------------
1886                 {
1887                     auto vec = Vector!(int, 6).build(1, 2, 3);
1888 
1889                     vec.emplaceBack(42);
1890                     assert(vec == [1, 2, 3, 42]);
1891 
1892                     vec.emplaceBack();
1893                     assert(vec == [1, 2, 3, 42, 0]);
1894                 }
1895 
1896                 {
1897                     static struct Foo{
1898                         int i;
1899                         string str;
1900                     }
1901 
1902                     auto vec = Vector!(Foo, 6).build(Foo(1, "A"));
1903 
1904                     vec.emplaceBack(2, "B");
1905                     assert(vec == only(Foo(1, "A"), Foo(2, "B")));
1906                 }
1907                 --------------------
1908         */
1909         public void emplaceBack(Args...)(auto ref Args args)scope{
1910             const size_t old_length = this.length;
1911             const size_t new_length = (old_length + 1);
1912 
1913             this.reserve(new_length);
1914             auto ptr = (()@trusted => this.ptr + old_length )();
1915 
1916             emplaceImpl(*ptr, forward!args);
1917 
1918             this.storage.length = new_length;
1919         }
1920 
1921 
1922 
1923         /**
1924             Extends the `Vector` by appending additional elements at the end of vector.
1925 
1926             Return index of first inserted element.
1927 
1928             Parameters:
1929                 `val` appended value.
1930 
1931                 `vec` appended vector.
1932 
1933                 `range` appended input renge.
1934 
1935                 `count` Number of times `val` is appended.
1936 
1937             Examples:
1938                 --------------------
1939                 {
1940                     auto vec = Vector!(int, 6).build(1, 2, 3);
1941 
1942                     vec.append(42);
1943                     assert(vec == [1, 2, 3, 42]);
1944                 }
1945 
1946                 {
1947                     auto vec = Vector!(int, 6).build(1, 2, 3);
1948 
1949                     vec.append(only(4, 5, 6));
1950                     assert(vec == [1, 2, 3, 4, 5, 6]);
1951                 }
1952 
1953                 {
1954                     auto a = Vector!(int, 6).build(1, 2, 3);
1955                     auto b = Vector!(int, 6).build(4, 5, 6);
1956 
1957                     a.append(b);
1958                     assert(a == [1, 2, 3, 4, 5, 6]);
1959                 }
1960 
1961                 {
1962                     Vector!(int, 3) vec = Vector!(int, 3).build(1, 2, 3);
1963                     int[3] tmp = [4, 5, 6];
1964                     vec.append(tmp[]);
1965                     assert(vec == [1, 2, 3, 4, 5, 6]);
1966                 }
1967 
1968                 {
1969                     struct Range{
1970                         int i;
1971 
1972                         bool empty()(){return i == 0;}
1973                         int front()(){return i;}
1974                         void popFront()(){i -= 1;}
1975                         //size_t length(); //no length
1976                     }
1977 
1978                     Vector!(int, 3) vec = Vector!(int, 3).build(6, 5, 4);
1979                     vec.append(Range(3));
1980                     assert(vec == [6, 5, 4, 3, 2, 1]);
1981                 }
1982                 --------------------
1983         */
1984         public size_t append(R)(R range)scope
1985         if(isBtlInputRange!R && is(ElementEncodingType!R : ElementType)){
1986             static if(hasLength!R){
1987                 return this._append_impl(forward!range);
1988             }
1989             else{
1990                 const len = this.length;
1991                 while(!range.empty){
1992                     this._append_impl(range.front);
1993                     range.popFront;
1994                 }
1995 
1996                 return len;
1997             }
1998         }
1999 
2000         /// ditto
2001         public size_t append(Vec)(scope auto ref Vec vec)scope
2002         if(isVector!Vec && is(GetElementType!Vec : ElementType)){
2003             return this.append(vec.storage.elements);
2004         }
2005 
2006         /// ditto
2007         public size_t append(Val)(auto ref Val val, const size_t count = 1)scope
2008         if(is(Val : ElementType)){
2009             return this._append_impl(forward!val, count);
2010         }
2011 
2012         private size_t _append_impl(Args...)(auto ref Args args)scope{
2013             const size_t args_length = emplaceLength(args);
2014             const size_t old_length = this.length;
2015             const size_t new_length = (old_length + args_length);
2016 
2017             this.reserve(new_length);
2018 
2019             {
2020                 ElementType[] elms = ()@trusted{
2021                     return this.ptr[old_length .. new_length];
2022                 }();
2023 
2024                 size_t emplaced = 0;
2025                 scope(failure)
2026                     this.storage.length = (old_length + emplaced);
2027 
2028                 emplaceElements(emplaced, elms, forward!args);
2029             }
2030 
2031             this.storage.length = new_length;
2032 
2033             return old_length;
2034         }
2035 
2036 
2037 
2038         /**
2039             Inserts additional elements into the `Vector` right before the element indicated by `pos` or `ptr`.
2040 
2041             Return index of first inserted element.
2042 
2043             Parameters:
2044                 `pos` Insertion point, the new contents are inserted before the element at position `pos`.
2045 
2046                 `ptr` Pointer pointing to the insertion point, the new contents are inserted before the element pointed by ptr.
2047 
2048                 `val` Value inserted before insertion point `pos` or `ptr`.
2049 
2050                 `vec` appended vector.
2051 
2052                 `range` appended input renge.
2053 
2054                 `count` Number of times `val` is inserted.
2055 
2056             Examples:
2057                 --------------------
2058                 //pos:
2059                 {
2060                     auto vec = Vector!(int, 3).build(1, 2, 3);
2061 
2062                     size_t pos = vec.insert(1, 42, 2);
2063                     assert(pos == 1);
2064                     assert(vec == [1, 42, 42, 2, 3]);
2065 
2066                     pos = vec.insert(100, 4, 3);
2067                     assert(pos == 5);
2068                     assert(vec == [1, 42, 42, 2, 3, 4, 4, 4]);
2069                 }
2070 
2071                 {
2072                     auto vec = Vector!(int, 3).build(1, 2, 3);
2073 
2074                     size_t pos = vec.insert(1, [20, 30, 40]);
2075                     assert(pos == 1);
2076                     assert(vec == [1, 20, 30, 40, 2, 3]);
2077 
2078                     pos = vec.insert(100, [4, 5, 6]);
2079                     assert(pos == 6);
2080                     assert(vec == [1, 20, 30, 40, 2, 3, 4, 5, 6]);
2081                 }
2082 
2083                 {
2084                     auto vec = Vector!(int, 3).build(1, 2, 3);
2085                     auto tmp = Vector!(int, 10).build(-1, -2, -3);
2086 
2087                     size_t pos = vec.insert(1, tmp);
2088                     assert(pos == 1);
2089                     assert(vec == [1, -1, -2, -3, 2, 3]);
2090 
2091                     pos = vec.insert(100, Vector!(int, 10).build(40, 50, 60));
2092                     assert(pos == 6);
2093                     assert(vec == [1, -1, -2, -3, 2, 3, 40, 50, 60]);
2094                 }
2095 
2096                 //ptr:
2097                 {
2098                     auto vec = Vector!(int, 3).build(1, 2, 3);
2099 
2100                     size_t pos = vec.insert(vec.ptr + 1, 42, 2);
2101                     assert(pos == 1);
2102                     assert(vec == [1, 42, 42, 2, 3]);
2103 
2104                     pos = vec.insert(vec.ptr + 100, 4, 3);
2105                     assert(pos == 5);
2106                     assert(vec == [1, 42, 42, 2, 3, 4, 4, 4]);
2107                 }
2108 
2109                 {
2110                     auto vec = Vector!(int, 3).build(1, 2, 3);
2111 
2112                     size_t pos = vec.insert(vec.ptr + 1, [20, 30, 40]);
2113                     assert(pos == 1);
2114                     assert(vec == [1, 20, 30, 40, 2, 3]);
2115 
2116                     pos = vec.insert(vec.ptr + 100, [4, 5, 6]);
2117                     assert(pos == 6);
2118                     assert(vec == [1, 20, 30, 40, 2, 3, 4, 5, 6]);
2119                 }
2120 
2121                 {
2122                     auto vec = Vector!(int, 3).build(1, 2, 3);
2123                     auto tmp = Vector!(int, 10).build(-1, -2, -3);
2124 
2125                     size_t pos = vec.insert(vec.ptr + 1, tmp);
2126                     assert(pos == 1);
2127                     assert(vec == [1, -1, -2, -3, 2, 3]);
2128 
2129                     pos = vec.insert(vec.ptr + 100, Vector!(int, 10).build(40, 50, 60));
2130                     assert(pos == 6);
2131                     assert(vec == [1, -1, -2, -3, 2, 3, 40, 50, 60]);
2132                 }
2133                 --------------------
2134         */
2135         public size_t insert(R)(const size_t pos, R range)scope
2136         if(    hasLength!R
2137             && isBtlInputRange!R
2138             && is(ElementEncodingType!R : ElementType)
2139         ){
2140             return this._insert_impl(pos, forward!range);
2141         }
2142 
2143         /// ditto
2144         public size_t insert(Vec)(const size_t pos, scope auto ref Vec vec)scope
2145         if(isVector!Vec && is(GetElementType!Vec : ElementType)){
2146             return this._insert_impl(pos, vec.storage.elements);
2147         }
2148 
2149         /// ditto
2150         public size_t insert(Val)(const size_t pos, auto ref Val val, const size_t count = 1)scope
2151         if(is(Val : ElementType)){
2152             return this._insert_impl(pos, forward!val, count);
2153         }
2154 
2155         /// ditto
2156         public size_t insert(R)(scope const ElementType* ptr, R range)scope
2157         if(isBtlInputRange!R && is(ElementEncodingType!R : ElementType)){
2158             static assert(hasLength!R, "range need length property");
2159 
2160             return this._insert_impl(ptr, forward!range);
2161         }
2162 
2163         /// ditto
2164         public size_t insert(Vec)(scope const ElementType* ptr, scope auto ref Vec vec)scope
2165         if(isVector!Vec && is(GetElementType!Vec : ElementType)){
2166             return this._insert_impl(ptr, vec.storage.elements);
2167         }
2168 
2169         /// ditto
2170         public size_t insert(Val)(scope const ElementType* ptr, auto ref Val val, const size_t count = 1)scope
2171         if(is(Val : ElementType)){
2172             return this._insert_impl(ptr, forward!val, count);
2173         }
2174 
2175         private size_t _insert_impl(Args...)(const size_t pos, auto ref Args args)scope{
2176 
2177             if(pos > this.length)
2178                 return this.append(forward!args);
2179 
2180             const size_t args_length = emplaceLength(args);
2181             const size_t old_length = this.length;
2182             const size_t new_length = (old_length + args_length);
2183 
2184             this.reserve(new_length);
2185 
2186             ElementType[] elms = (()@trusted => this.ptr[pos .. pos + args_length])();
2187 
2188             moveEmplaceRangeImpl(
2189                 (()@trusted => elms.ptr + args_length )(),
2190                 (()@trusted => elms.ptr )(),
2191                 (old_length - pos)  //shift
2192             );
2193 
2194             this.storage.length = new_length;
2195 
2196             {
2197                 size_t emplaced = 0;
2198                 scope(failure)
2199                     initElements(elms[emplaced .. $]);
2200 
2201                 emplaceElements(emplaced, elms, forward!args);
2202             }
2203 
2204 
2205             return pos;
2206         }
2207 
2208         private size_t _insert_impl(Args...)(scope const ElementType* ptr, auto ref Args args)scope{
2209             const size_t pos = (ptr > this.ptr)
2210                 ? (ptr - this.ptr)
2211                 : 0;
2212 
2213             return this._insert_impl(pos, forward!args);
2214         }
2215 
2216 
2217 
2218         /**
2219             Removes specified element from the vector.
2220 
2221             Return index of first removed element.
2222 
2223             Parameters:
2224                 `pos` position of first element to be removed.
2225 
2226                 `n` number of elements to be removed.
2227 
2228                 `ptr` pointer to elements to be removed.
2229 
2230                 `slice` sub-slice to be removed, `slice` must be subset of `this`
2231 
2232             Examples:
2233                 --------------------
2234                 //pos:
2235                 {
2236                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2237 
2238                     size_t pos = vec.erase(3);
2239                     assert(pos == 3);
2240                     assert(vec == [1, 2, 3]);
2241 
2242                     pos = vec.erase(100);
2243                     assert(pos == 3);
2244                     assert(vec == [1, 2, 3]);
2245                 }
2246 
2247                 {
2248                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2249 
2250                     size_t pos = vec.erase(1, 4);
2251                     assert(pos == 1);
2252                     assert(vec == [1, 6]);
2253 
2254                     pos = vec.erase(100, 4);
2255                     assert(pos == 2);
2256                     assert(vec == [1, 6]);
2257 
2258                     pos = vec.erase(0, 100);
2259                     assert(pos == 0);
2260                     assert(vec.empty);
2261                 }
2262 
2263                 //ptr:
2264                 {
2265                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2266 
2267                     size_t pos = vec.erase(vec.ptr + 3);
2268                     assert(pos == 3);
2269                     assert(vec == [1, 2, 3]);
2270 
2271                     pos = vec.erase(vec.ptr + 100);
2272                     assert(pos == 3);
2273                     assert(vec == [1, 2, 3]);
2274                 }
2275 
2276                 {
2277                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2278 
2279                     size_t pos = vec.erase(vec[1 .. 5]);
2280                     assert(pos == 1);
2281                     assert(vec == [1, 6]);
2282                 }
2283                 --------------------
2284         */
2285         public size_t erase()(const size_t pos)scope nothrow{
2286             const size_t old_length = this.length;
2287 
2288             if(pos >= old_length)
2289                 return old_length;
2290 
2291             ElementType[] elements = this.storage.elements[pos .. old_length];
2292             destructRangeImpl!false(elements);
2293 
2294             this.storage.length = pos;
2295 
2296             return pos;
2297         }
2298 
2299         /// ditto
2300         public size_t erase()(const size_t pos, const size_t n)scope{
2301             const size_t old_length = this.length;
2302 
2303             if(pos >= old_length)
2304                 return old_length;
2305 
2306             const size_t top = (pos + n);
2307 
2308             if(top >= old_length)
2309                 return this.erase(pos);
2310 
2311             if(n != 0){
2312                 ElementType[] elements = this.storage.elements;
2313 
2314                 destructRangeImpl!false(elements[pos .. top]);
2315 
2316                 moveEmplaceRangeImpl(
2317                     (()@trusted => elements.ptr + pos )(),
2318                     (()@trusted => elements.ptr + top )(),
2319                     (old_length - top)
2320                 );
2321 
2322                 this.storage.length = (old_length - n);
2323             }
2324 
2325             return pos;
2326         }
2327 
2328         /// ditto
2329         public size_t erase()(scope const ElementType* ptr)scope nothrow{
2330             if(ptr <= this.ptr){
2331                 this.clear();
2332                 return 0;
2333             }
2334 
2335             return this.erase(ptr - this.ptr);
2336         }
2337 
2338         /// ditto
2339         public size_t erase()(scope const ElementType[] slice)scope nothrow @safe{
2340             const ptr = (()@trusted => this.ptr )();
2341 
2342             if(slice.ptr < ptr){
2343                 const size_t offset = (()@trusted => ptr - slice.ptr)();
2344 
2345                 if(offset >= slice.length)
2346                     return 0;
2347 
2348                 return this.erase(0, slice.length - offset);
2349             }
2350 
2351             debug assert(slice.ptr >= ptr);
2352 
2353             const size_t pos = (()@trusted => slice.ptr - ptr )();
2354 
2355             return this.erase(pos, slice.length);
2356         }
2357 
2358 
2359         /**
2360             Replaces the portion of the vector that begins at element `pos` and spans `len` characters (or the part of the vector in the slice `slice`) by new contents.
2361 
2362             Parameters:
2363                 `pos` position of the first character to be replaced.
2364 
2365                 `len` number of elements to replace (if the vector is shorter, as many elements as possible are replaced).
2366 
2367                 `slice` sub-slice to be removed, `slice` must be subset of `this`
2368 
2369                 `val` inserted value.
2370 
2371                 `count` number of times `val` is inserted.
2372 
2373             Examples:
2374                 --------------------
2375                 //pos:
2376                 {
2377                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2378 
2379                     size_t pos = vec.replace(2, 2, 0, 5);
2380                     assert(pos == 2);
2381                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2382 
2383                     pos = vec.replace(100, 2, 42, 2);
2384                     assert(pos == 9);
2385                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2386 
2387                     pos = vec.replace(2, 100, -1);
2388                     assert(pos == 2);
2389                     assert(vec == [1, 2,  -1]);
2390                 }
2391 
2392                 {
2393                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2394 
2395                     size_t pos = vec.replace(2, 2, [0, 0, 0, 0, 0]);
2396                     assert(pos == 2);
2397                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2398 
2399                     pos = vec.replace(100, 2, [42, 42]);
2400                     assert(pos == 9);
2401                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2402 
2403                     pos = vec.replace(2, 100, [-1]);
2404                     assert(pos == 2);
2405                     assert(vec == [1, 2,  -1]);
2406                 }
2407 
2408                 {
2409                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2410 
2411                     size_t pos = vec.replace(2, 2, Vector!(int, 3).build(0, 0, 0, 0, 0));
2412                     assert(pos == 2);
2413                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2414 
2415                     pos = vec.replace(100, 2, Vector!(int, 2).build(42, 42));
2416                     assert(pos == 9);
2417                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2418 
2419                     pos = vec.replace(2, 100, Vector!(int, 2).build(-1));
2420                     assert(pos == 2);
2421                     assert(vec == [1, 2,  -1]);
2422                 }
2423 
2424                 //ptr:
2425                 {
2426                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2427 
2428                     size_t pos = vec.replace(vec[2 .. 4], 0, 5);
2429                     assert(pos == 2);
2430                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2431 
2432                     pos = vec.replace(vec.ptr[100 .. 102], 42, 2);
2433                     assert(pos == 9);
2434                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2435 
2436                     pos = vec.replace(vec.ptr[2 .. 100], -1);
2437                     assert(pos == 2);
2438                     assert(vec == [1, 2,  -1]);
2439                 }
2440 
2441                 {
2442                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2443 
2444                     size_t pos = vec.replace(vec[2 .. 4], [0, 0, 0, 0, 0]);
2445                     assert(pos == 2);
2446                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2447 
2448                     pos = vec.replace(vec.ptr[100 .. 102], [42, 42]);
2449                     assert(pos == 9);
2450                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2451 
2452                     pos = vec.replace(vec.ptr[2 .. 100], [-1]);
2453                     assert(pos == 2);
2454                     assert(vec == [1, 2,  -1]);
2455                 }
2456 
2457                 {
2458                     auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
2459 
2460                     size_t pos = vec.replace(vec[2 .. 4], Vector!(int, 3).build(0, 0, 0, 0, 0));
2461                     assert(pos == 2);
2462                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
2463 
2464                     pos = vec.replace(vec.ptr[100 .. 102], Vector!(int, 2).build(42, 42));
2465                     assert(pos == 9);
2466                     assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
2467 
2468                     pos = vec.replace(vec.ptr[2 .. 100], Vector!(int, 2).build(-1));
2469                     assert(pos == 2);
2470                     assert(vec == [1, 2,  -1]);
2471                 }
2472                 --------------------
2473         */
2474         public size_t replace(Val)(const size_t pos, const size_t len, auto ref Val val, const size_t count = 1)scope
2475         if(is(Val : ElementType)){
2476             return this._replace_impl(pos, len, forward!val, count);
2477         }
2478 
2479         /// ditto
2480         public size_t replace(R)(const size_t pos, const size_t len, R range)scope
2481         if(    hasLength!R
2482             && isBtlInputRange!R
2483             && is(ElementEncodingType!R : ElementType)
2484         ){
2485             return this._replace_impl(pos, len, forward!range);
2486         }
2487 
2488         /// ditto
2489         public size_t replace(Vec)(const size_t pos, const size_t len, scope auto ref Vec vec)scope
2490         if(isVector!Vec && is(GetElementType!Vec : ElementType)){
2491             return this._replace_impl(pos, len, vec.storage.elements);
2492         }
2493 
2494         /// ditto
2495         public size_t replace(Val)(scope const ElementType[] slice, auto ref Val val, const size_t count = 1)scope
2496         if(is(Val : ElementType)){
2497             return this._replace_impl(slice, forward!val, count);
2498         }
2499 
2500         /// ditto
2501         public size_t replace(R)(scope const ElementType[] slice, R range)scope
2502         if(    hasLength!R
2503             && isBtlInputRange!R
2504             && is(ElementEncodingType!R : ElementType)
2505         ){
2506             return this._replace_impl(slice, forward!range);
2507         }
2508 
2509         /// ditto
2510         public size_t replace(Vec)(scope const ElementType[] slice, scope auto ref Vec vec)scope
2511         if(isVector!Vec && is(GetElementType!Vec : ElementType)){
2512             return this._replace_impl(slice, vec.storage.elements);
2513         }
2514 
2515 
2516         private size_t _replace_impl(Args...)(const size_t pos, const size_t len, auto ref Args args)scope{
2517             const size_t old_length = this.length;
2518 
2519             if(len == 0){
2520                 return this.insert(pos, forward!args);
2521             }
2522 
2523             if(old_length <= pos){
2524                 return this.append(forward!args);
2525             }
2526 
2527             const size_t top = (pos + len);
2528 
2529             if(top >= old_length){
2530                 this.erase(pos);
2531                 return this.append(forward!args);
2532             }
2533 
2534             const size_t args_length = emplaceLength(args);
2535             alias erase_length = len;
2536 
2537             if(args_length == erase_length){
2538                 ElementType[] elements = this.storage.elements;
2539                 ElementType[] elms = elements[pos .. top];
2540                 destructRangeImpl!false(elms);
2541 
2542                 {
2543                     size_t emplaced = 0;
2544                     scope(failure)
2545                         initElements(elms[emplaced .. $]);
2546 
2547                     emplaceElements(emplaced, elms, forward!args);
2548                 }
2549 
2550                 return pos;
2551             }
2552 
2553             if(args_length < erase_length){
2554                 const size_t diff = (erase_length - args_length);
2555                 const size_t new_length = (old_length - diff);
2556 
2557                 ElementType[] elements = this.storage.elements;
2558                 ElementType[] old_elms = elements[pos .. top];
2559                 ElementType[] new_elms = elements[pos .. pos + args_length];
2560 
2561                 destructRangeImpl!false(old_elms);
2562 
2563                 moveEmplaceRangeImpl(
2564                     (()@trusted => elements.ptr + top )(),
2565                     (()@trusted => elements.ptr + top - diff )(),
2566                     diff
2567                 );
2568 
2569                 this.storage.length = new_length;
2570 
2571                 {
2572                     size_t emplaced = 0;
2573                     scope(failure)
2574                         initElements(new_elms[emplaced .. $]);
2575 
2576                     emplaceElements(emplaced, new_elms, forward!args);
2577                 }
2578 
2579 
2580                 return pos;
2581             }
2582 
2583             assert(args_length > erase_length);
2584             {
2585                 const size_t diff = (args_length - erase_length);
2586                 const size_t new_length = (old_length + diff);
2587 
2588                 this.reserve(new_length);
2589 
2590                 ElementType[] elements = (()@trusted => this.storage.allocatedElements)();
2591                 ElementType[] old_elms = elements[pos .. top];
2592                 ElementType[] new_elms = elements[pos .. pos + args_length];
2593 
2594                 destructRangeImpl!false(old_elms);
2595 
2596                 moveEmplaceRangeImpl(
2597                     (()@trusted => elements.ptr + top + diff )(),
2598                     (()@trusted => elements.ptr + top )(),
2599                     diff
2600                 );
2601 
2602                 this.storage.length = new_length;
2603 
2604                 {
2605                     size_t emplaced = 0;
2606                     scope(failure)
2607                         initElements(new_elms[emplaced .. $]);
2608 
2609                     emplaceElements(emplaced, new_elms, forward!args);
2610                 }
2611 
2612                 return pos;
2613             }
2614         }
2615 
2616         private size_t _replace_impl(Args...)(scope const ElementType[] slice, auto ref Args args)scope{
2617             const ptr = (()@trusted => this.ptr )();
2618 
2619             if(slice.ptr < ptr){
2620                 const size_t offset = (()@trusted => ptr - slice.ptr)();
2621 
2622                 return (offset >= slice.length)
2623                     ? this.insert(0, forward!args)
2624                     : this.replace(0, slice.length - offset, forward!args);
2625             }
2626 
2627             debug assert(slice.ptr >= ptr);
2628 
2629             const size_t pos = (()@trusted => slice.ptr - ptr )();
2630 
2631             return this.replace(pos, slice.length, forward!args);
2632         }
2633 
2634 
2635 
2636         ///Alias to append.
2637         public alias put = append;
2638 
2639 
2640 
2641         /**
2642             Returns a reference to the first element in the vector.
2643 
2644             Calling this function on an empty container causes undefined behavior.
2645         */
2646         public ref inout(ElementType) front()inout return pure nothrow @system @nogc{
2647             this._bounds_check(0);
2648             return *this.ptr;
2649         }
2650 
2651 
2652 
2653         /**
2654             Returns a copy of the first element in the vector.
2655 
2656             Examples:
2657                 --------------------
2658                 auto vec = Vector!(int, 10).build(1, 2, 3);
2659 
2660                 assert(vec.frontCopy == 1);
2661                 assert(vec == [1, 2, 3]);
2662                 --------------------
2663         */
2664         public auto frontCopy(this This)()scope{
2665             this._bounds_check(0);
2666 
2667             return *(()@trusted => this.ptr )();
2668         }
2669 
2670 
2671 
2672         /**
2673             Move of the first element in the vector and return it.
2674 
2675             Examples:
2676                 --------------------
2677                 auto vec = Vector!(int, 10).build(1, 2, 3);
2678 
2679                 assert(vec.moveFront == 1);
2680                 assert(vec == [0, 2, 3]);
2681                 --------------------
2682         */
2683         public ElementType moveFront()()scope{
2684             this._bounds_check(0);
2685 
2686             return move(*(()@trusted => this.ptr )());
2687         }
2688 
2689 
2690 
2691         /**
2692             Returns a reference to the last element in the vector.
2693 
2694             Calling this function on an empty container causes undefined behavior.
2695         */
2696         public ref inout(ElementType) back()inout return pure nothrow @system @nogc{
2697             this._bounds_check(0);            
2698 
2699             return *((this.ptr - 1) + this.length) ;
2700         }
2701 
2702 
2703 
2704         /**
2705             Returns a copy of the first element in the vector.
2706 
2707             Examples:
2708                 --------------------
2709                 auto vec = Vector!(int, 10).build(1, 2, 3);
2710 
2711                 assert(vec.backCopy == 3);
2712                 assert(vec == [1, 2, 3]);
2713                 --------------------
2714         */
2715         public auto backCopy(this This)()scope{
2716             this._bounds_check(0);
2717 
2718             return *(()@trusted => (this.ptr + (length - 1)) )();
2719         }
2720 
2721 
2722 
2723         /**
2724             Move of the last element in the vector and return it.
2725 
2726             Examples:
2727                 --------------------
2728                 auto vec = Vector!(int, 10).build(1, 2, 3);
2729 
2730                 assert(vec.moveBack == 3);
2731                 assert(vec == [1, 2, 0]);
2732                 --------------------
2733         */
2734         public ElementType moveBack()()scope{
2735             this._bounds_check(0);
2736             return *(()@trusted => (this.ptr + (length - 1)) )();
2737         }
2738 
2739 
2740 
2741         /**
2742             Static function which return `Vector` construct from arguments `args`.
2743 
2744             Parameters:
2745                 `allocator` exists only if template parameter `_Allocator` has state.
2746 
2747                 `args` values of type `ElementType`, input range or `Vector`.
2748 
2749             Examples:
2750                 --------------------
2751                 import std.range : only;
2752 
2753                 auto vec = Vector!(int, 6).build(1, 2, [3, 4], only(5, 6), Vector!(int, 10).build(7, 8));
2754                 assert(vec == [1, 2, 3, 4, 5, 6, 7, 8]);
2755                 --------------------
2756         */
2757         public static typeof(this) build(Args...)(auto ref Args args){
2758             import core.lifetime : forward;
2759 
2760             auto result = Vector.init;
2761 
2762             result._build_impl(forward!args);
2763 
2764             return ()@trusted{
2765                 return *&result;
2766             }();
2767         }
2768 
2769         /// ditto
2770         static if(allowHeap)
2771         public static typeof(this) build(Args...)(AllocatorType allocator, auto ref Args args){
2772             import core.lifetime : forward;
2773 
2774             auto result = (()@trusted => Vector(forward!allocator))();
2775 
2776             result._build_impl(forward!args);
2777 
2778             return ()@trusted{
2779                 return *&result;
2780             }();
2781         }
2782 
2783         private void _build_impl(Args...)(auto ref Args args)scope{
2784             import std.traits : isArray;
2785 
2786             assert(this.empty);
2787 
2788             size_t new_length = 0;
2789 
2790             foreach(ref arg; args)
2791                 new_length += emplaceLength(arg);
2792 
2793 
2794             if(new_length == 0)
2795                 return;
2796 
2797             this.reserve(new_length);
2798 
2799 
2800             /+foreach(alias arg; args)
2801                 this.append(forward!arg);
2802             +/
2803 
2804             ElementType* ptr = (()@trusted => this.ptr )();
2805 
2806             foreach(alias arg; args){
2807                 const size_t len = emplaceLength(arg);
2808 
2809                 ElementType[] elms = (()@trusted => ptr[0 .. len] )();
2810 
2811                 {
2812                     size_t emplaced = 0;
2813                     scope(failure)
2814                         this.storage.length = (this.length + emplaced);
2815 
2816                     emplaceElements(emplaced, elms, forward!arg);
2817                 }
2818 
2819 
2820                 ()@trusted{
2821                     ptr += len;
2822                 }();
2823 
2824                 this.storage.length = (this.length + len);
2825             }
2826         }
2827 
2828 
2829 
2830         //internals:
2831         private Storage storage;
2832 
2833         static if(!allowHeap)
2834             private alias _allocator = statelessAllcoator!NullAllocator;   
2835         else static if(hasStatelessAllocator)
2836             private alias _allocator = statelessAllcoator!AllocatorType;        
2837         else
2838             private AllocatorType _allocator;
2839 
2840 
2841         //enforce:
2842         private void _enforce(bool con, string msg)const pure nothrow @safe @nogc{
2843             if(!con)assert(0, msg);
2844         }
2845 
2846         //grow:
2847         private static size_t _grow_capacity(size_t old_capacity, size_t new_capacity)pure nothrow @safe @nogc{
2848             static if(minimalCapacity == 0)
2849                 return max(2, old_capacity * 2, new_capacity);
2850             else
2851                 return max(old_capacity * 2, new_capacity);
2852         }
2853 
2854         //allocation:
2855         private void _allocate_heap()(ref Storage.Heap heap, size_t new_capacity)scope nothrow{
2856             new_capacity = Storage.heapCapacity(new_capacity);
2857 
2858             void[] data = _allocator.allocate(new_capacity * ElementType.sizeof);
2859 
2860             _enforce(data.length != 0, "allocation fail");
2861 
2862             static if(supportGC)
2863                 gcAddRange(data);
2864 
2865             heap.ptr = (()@trusted => cast(ElementType*)data.ptr )();
2866             heap.capacity = new_capacity;
2867         }
2868 
2869         private void _deallocate_heap()(const ref Storage.Heap heap)scope nothrow{
2870             void[] data = ()@trusted{
2871                 return cast(void[])heap.data;
2872             }();
2873 
2874             static if(supportGC)
2875                 gcRemoveRange(data);
2876 
2877             static if(safeAllcoate!(typeof(_allocator)))
2878                 const d = ()@trusted{
2879                     return _allocator.deallocate(data);
2880                 }();
2881 
2882             else
2883                 const d = _allocator.deallocate(data);
2884 
2885             _enforce(d, "deallocation fail");
2886         }
2887 
2888         private void _reallocate_heap(bool optional = false)(ref Storage.Heap heap, size_t new_capacity, const size_t length)scope nothrow{
2889             new_capacity = Storage.heapCapacity(new_capacity);
2890 
2891             import std.traits : hasElaborateMove;
2892 
2893             if(heap.capacity >= new_capacity)
2894                 return;
2895 
2896             void[] data = heap.data;
2897             void[] old_data = data;
2898 
2899             static if(!hasElaborateMove!ElementType){
2900                 static if(safeAllcoate!(typeof(_allocator)))
2901                     const bool reallcoated = ()@trusted{
2902                         return _allocator.reallocate(data, new_capacity * ElementType.sizeof);
2903                     }();
2904                 else
2905                     const bool reallcoated = _allocator.reallocate(data, new_capacity * ElementType.sizeof);
2906 
2907                 if(reallcoated){
2908                     heap.ptr = (()@trusted => cast(ElementType*)data.ptr )();
2909                     heap.capacity = new_capacity;
2910 
2911                     static if(supportGC){
2912                         gcRemoveRange(old_data);
2913                         gcAddRange(data);
2914                     }
2915 
2916                     return;
2917                 }
2918             }
2919 
2920 
2921             static if(!optional){
2922                 Storage.Heap heap_new;
2923 
2924                 {
2925                     this._allocate_heap(heap_new, new_capacity);
2926 
2927                     moveEmplaceRangeImpl!false(
2928                         (()@trusted => heap_new.ptr )(),
2929                         (()@trusted => heap.ptr )(),
2930                         length
2931                     );
2932                 }
2933 
2934                 this._deallocate_heap(heap);
2935 
2936                 heap = heap_new;
2937             }
2938         }
2939 
2940         //bounds check:
2941         private pragma(inline, true) void _bounds_check(const size_t pos)const pure nothrow @safe @nogc{
2942             assert(pos < this.length);
2943 
2944             version(BTL_VECTOR_BOUNDS_CHECK){
2945                 if(pos >= this.length){
2946                     assert(0, "btl.vector bounds check error");
2947                 }
2948             }
2949         }
2950 
2951         private pragma(inline, true) void _bounds_check(const size_t pos, const size_t len)const pure nothrow @safe @nogc{
2952             assert(pos <= this.length);
2953             assert((pos + len) <= this.length);
2954 
2955             version(BTL_VECTOR_BOUNDS_CHECK){
2956                 if(pos > this.length){
2957                     assert(0, "btl.vector bounds check error");
2958                 }
2959                 if((pos + len) > this.length){
2960                     assert(0, "btl.vector bounds check error");
2961                 }
2962             }
2963         }
2964 
2965         private pragma(inline, true) void _bounds_check(const size_t[2] index)const pure nothrow @safe @nogc{
2966             assert(index[0] <= this.length);
2967             assert(index[1] <= this.length);
2968 
2969             version(BTL_VECTOR_BOUNDS_CHECK){
2970                 if(index[0] > this.length){
2971                     assert(0, "btl.vector bounds check error");
2972                 }
2973                 if(index[1] > this.length){
2974                     assert(0, "btl.vector bounds check error");
2975                 }
2976             }
2977         }
2978 
2979     }
2980 
2981 
2982     private{
2983 
2984         static size_t emplaceLength(Val)(ref Val val)
2985         if(is(immutable Val : immutable _Type)){
2986             return 1;
2987         }
2988 
2989         static size_t emplaceLength(Val)(ref Val val, const size_t count)
2990         if(is(immutable Val : immutable _Type)){
2991             return count;
2992         }
2993 
2994         static size_t emplaceLength(Vec)(ref Vec vec)
2995         if(isVector!Vec && is(immutable Vec.ElementType == immutable _Type)){
2996             return vec.length;
2997         }
2998 
2999         static size_t emplaceLength(R)(ref R range)
3000         if(hasLength!R && isBtlInputRange!R && is(immutable ElementEncodingType!R : immutable _Type)){
3001             return range.length;
3002         }
3003 
3004 
3005 
3006         static void emplaceElements(T, Val)(ref size_t emplaced, T[] slice, auto ref Val val, const size_t count)
3007         if(is(immutable Val : immutable _Type)){
3008             assert(slice.length == count);
3009 
3010             foreach(ref elm; slice){
3011                 emplaceImpl(elm, val);
3012                 emplaced += 1;
3013             }
3014         }
3015 
3016         static void emplaceElements(T, Val)(ref size_t emplaced, T[] slice, auto ref Val val)
3017         if(is(immutable Val : immutable _Type)){
3018             assert(slice.length == 1);
3019 
3020             foreach(ref elm; slice){
3021                 emplaceImpl(elm, val);
3022                 emplaced += 1;
3023             }
3024         }
3025 
3026         static void emplaceElements(T, R)(ref size_t emplaced, T[] slice, R range)
3027         if(hasLength!R && isBtlInputRange!R && is(immutable ElementEncodingType!R : immutable _Type)){
3028             //TODO trivial copy
3029             auto ptr = (()@trusted => slice.ptr )();
3030 
3031             debug auto end_ptr = (()@trusted => ptr + slice.length )();
3032 
3033             while(!range.empty){
3034                 debug assert(ptr < end_ptr);
3035 
3036                 emplaceImpl(*ptr, range.front);
3037                 emplaced += 1;
3038 
3039                 range.popFront();
3040                 ()@trusted{
3041                     ptr += 1;
3042                 }();
3043             }
3044         }
3045 
3046         static void emplaceElements(T, Vec)(ref size_t emplaced, T[] slice, scope auto ref Vec vec)
3047         if(isVector!Vec && is(immutable Vec.ElementType == immutable _Type)){
3048             emplaceElements(emplaced, slice, (()@trusted => vec.elements )() );
3049         }
3050 
3051         static void emplaceElements(T)(ref size_t emplaced, T[] slice){
3052 
3053             /// TODO emplaceRangeImpl if nothrow ctors
3054             foreach(ref elm; slice){
3055                 emplaceImpl(elm);
3056                 emplaced += 1;
3057             }
3058         }
3059 
3060         static void emplaceElementsArgs(T, Args...)(ref size_t emplaced, T[] slice, auto ref Args args){
3061 
3062             /// TODO emplaceRangeImpl if nothrow ctors
3063             foreach(ref elm; slice){
3064                 emplaceImpl(elm, args);
3065                 emplaced += 1;
3066             }
3067         }
3068 
3069 
3070 
3071         static void initElements(T)(T[] elements)nothrow{
3072             enum has_init = __traits(compiles, (ref _Type elm) => emplaceElement(elm));
3073 
3074             static if(has_init){
3075                 foreach(ref elm; elements)
3076                     emplaceElement(elm);
3077                 return true;
3078             }
3079             else{
3080                 import std.traits : Unqual;
3081 
3082                 assert(0, "fatal error: " ~ Unqual!T.stringof ~ " has @disabled init");
3083 
3084             }
3085         }
3086 
3087     }
3088 }
3089 
3090 /// Alias to `Vector` with different order of template parameters
3091 template Vector(
3092     _Type,
3093     _Allocator,
3094     bool _supportGC = shouldAddGCRange!_Type
3095 ){
3096     alias Vector = .Vector!(_Type, 0, _Allocator, _supportGC);
3097 }
3098 
3099 ///
3100 pure nothrow @nogc unittest{
3101     import std.range : only;
3102     import std.algorithm : map, equal;
3103 
3104     static struct Foo{
3105         int i;
3106         string str;
3107     }
3108 
3109     Vector!(Foo, 4) vec;
3110 
3111     assert(vec.empty);
3112     assert(vec.capacity == 4);
3113     assert(typeof(vec).minimalCapacity == 4);
3114 
3115     vec.append(Foo(1, "A"));
3116     assert(vec.length == 1);
3117 
3118     vec.append(only(Foo(2, "B"), Foo(3, "C")));
3119     assert(vec.length == 3);
3120 
3121     vec.emplaceBack(4, "D");
3122     assert(vec.length == 4);
3123     assert(vec.capacity == 4);
3124 
3125     vec.insert(1, Foo(5, "E"));
3126     assert(vec.length == 5);
3127     assert(vec.capacity > 4);
3128     assert(equal(vec[].map!(e => e.str), only("A", "E", "B", "C", "D")));
3129 
3130     vec.erase(vec[1 .. $-1]);   //same as vec.erase(1, 3);
3131     assert(vec == only(Foo(1, "A"), Foo(4, "D")));
3132 
3133 
3134     vec = Vector!(Foo, 2).build(Foo(-1, "X"), Foo(-2, "Y"));
3135     assert(equal(vec[].map!(e => e.str), only("X", "Y")));
3136 
3137 
3138     vec.clear();
3139     assert(vec.length == 0);
3140     assert(vec.capacity > 4);
3141 
3142     vec.release();
3143     assert(vec.length == 0);
3144     assert(vec.capacity == typeof(vec).minimalCapacity);
3145 
3146 }
3147 
3148 
3149 /// Alias to `Vector` with `void` allcoator
3150 template FixedVector(
3151     _Type,
3152     size_t N ,
3153     bool _supportGC = shouldAddGCRange!_Type
3154 )
3155 if(N > 0){
3156     alias FixedVector = .Vector!(_Type, N, void, _supportGC);
3157 }
3158 
3159 
3160 /// Alias to `Vector` with with `N > 0`
3161 template SmallVector(
3162     _Type,
3163     size_t N ,
3164     _Allocator = DefaultAllocator,
3165     bool _supportGC = shouldAddGCRange!_Type
3166 )
3167 if(N > 0){
3168     alias SmallVector = .Vector!(_Type, N, _Allocator, _supportGC);
3169 }
3170 
3171 
3172 
3173 
3174 public alias hasCopyConstructor_SP = hasCopyConstructor;
3175 //local traits:
3176 package{
3177 
3178     enum bool safeAllcoate(A) = __traits(compiles, (ref A allcoator)@safe{
3179         const size_t size;
3180         allcoator.allocate(size);
3181     }(*cast(A*)null));
3182 
3183 
3184     //copy ctor:
3185     template hasCopyConstructor(From, To)
3186     if(is(immutable From == immutable To)){
3187 
3188         enum bool hasCopyConstructor = true
3189             && !is(From == shared)
3190             && isConstructable!(From, To)
3191             && isCopyConstructableElement!( 
3192                 GetElementType!From, 
3193                 GetElementType!To
3194             )
3195             && (From.hasStatelessAllocator 
3196                 || isCopyConstructableElement!(
3197                     GetAllocatorType!From,
3198                     GetAllocatorType!To
3199                 )
3200             )
3201             && (From.hasStatelessAllocator 
3202                 || isCopyConstructableElement!(
3203                     GetAllocatorType!From,
3204                     To.AllocatorType
3205                 )
3206             );
3207     }
3208 
3209     //Move Constructable:
3210     template isMoveConstructable(alias from, To){
3211         alias From = typeof(from);
3212 
3213         enum isMoveConstructable = true
3214             && !isRef!from
3215             && isConstructable!(From, To)
3216             && is(GetElementReferenceType!From : GetElementReferenceType!To)
3217             && is(immutable From.AllocatorType == immutable To.AllocatorType)
3218             && (From.hasStatelessAllocator 
3219                 || isMoveConstructableElement!(
3220                         GetAllocatorType!From,
3221                         GetAllocatorType!To
3222                 )
3223             );
3224     }
3225 
3226     //Move Assignable:
3227     template isMoveAssignable(alias from, To){
3228         alias From = typeof(from);
3229 
3230         enum isMoveAssignable = true
3231             && !isRef!from
3232             && isAssignable!(From, To)   
3233             && is(GetElementReferenceType!From : GetElementReferenceType!To)
3234             && is(immutable From.AllocatorType == immutable To.AllocatorType)
3235             && (From.hasStatelessAllocator 
3236                 || isMoveAssignableElement!(
3237                         GetAllocatorType!From,
3238                         GetAllocatorType!To
3239                 )
3240             );
3241     }
3242 
3243     //Constructable:
3244     template isConstructable(From, To){
3245 
3246         enum isConstructable = true
3247             && !is(From == shared)
3248             && (From.supportGC == To.supportGC)
3249             && is(GetElementType!From : GetElementType!To)
3250             && (From.hasStatelessAllocator
3251                 ? is(immutable From.AllocatorType == immutable To.AllocatorType)
3252                 : is(immutable From.AllocatorType : immutable To.AllocatorType)
3253             );
3254     }
3255 
3256     //Assignable:
3257     template isAssignable(From, To){
3258         import std.traits : isMutable;
3259 
3260         enum isAssignable = true
3261             && isMutable!To
3262             && !is(From == shared) && !is(To == shared)
3263             && (From.supportGC == To.supportGC)
3264             && is(GetElementType!From : GetElementType!To);
3265     }
3266 
3267 
3268     
3269     template GetElementType(Vec){
3270         alias GetElementType = CopyTypeQualifiers!(Vec, Vec.ElementType);
3271     }
3272 
3273     template GetAllocatorType(Vec){
3274         alias GetAllocatorType = CopyTypeQualifiers!(Vec, Vec.AllocatorType);
3275     }
3276 
3277     template GetElementReferenceType(Vec){
3278         alias GetElementReferenceType = ElementReferenceTypeImpl!(GetElementType!Vec);
3279     }
3280 
3281     template ElementReferenceTypeImpl(T){
3282         import std.traits : Select, isDynamicArray;
3283         import std.range : ElementEncodingType;
3284 
3285         static if(false
3286             || is(T == class) || is(T == interface)
3287             || is(T == function) || is(T == delegate)
3288             || is(T : U*, U)
3289         ){
3290             alias ElementReferenceTypeImpl = T;
3291         }
3292         else static if(isDynamicArray!T){
3293             alias ElementReferenceTypeImpl = ElementEncodingType!T[];
3294         }
3295         else{
3296             alias ElementReferenceTypeImpl = T*;
3297         }
3298     }
3299 
3300 
3301 }
3302 
3303 
3304 //Vector examples:
3305 version(unittest){
3306 
3307     private alias ZeroVector(T, size_t N, A = Mallocator) = .Vector!(T, 0, A);
3308 
3309     import std.range : only;
3310     static foreach(alias Vector; AliasSeq!(.Vector, ZeroVector)){
3311 
3312         //Vector.minimalCapacity
3313         pure nothrow @safe @nogc unittest{
3314             Vector!(int, 10) vec;
3315             assert(vec.capacity == typeof(vec).minimalCapacity);
3316         }
3317 
3318         //Vector.empty
3319         pure nothrow @safe @nogc unittest{
3320             Vector!(int, 10) vec;
3321             assert(vec.empty);
3322 
3323             vec.append(42);
3324             assert(!vec.empty);
3325         }
3326 
3327         //Vector.full
3328         pure nothrow @safe @nogc unittest{
3329             Vector!(int, 4, void) vec;  //FixedVector
3330             assert(vec.empty);
3331             assert(vec.maximalCapacity == vec.minimalCapacity);
3332 
3333             vec.resize(vec.maximalCapacity);
3334             assert(vec.full);
3335         }
3336 
3337         //Vector.length
3338         pure nothrow @safe @nogc unittest{
3339             Vector!(int, 10) vec = null;
3340             assert(vec.length == 0);
3341 
3342             vec.append(42);
3343             assert(vec.length == 1);
3344 
3345             vec.append(123);
3346             assert(vec.length == 2);
3347 
3348             vec.clear();
3349             assert(vec.length == 0);
3350         }
3351 
3352         //Vector.capacity
3353         pure nothrow @safe @nogc unittest{
3354             Vector!(int, 10) vec;
3355             assert(vec.capacity == typeof(vec).minimalCapacity);
3356 
3357             vec.reserve(max(2, vec.capacity * 2));
3358             assert(vec.capacity > typeof(vec).minimalCapacity);
3359         }
3360 
3361         //Vector.ptr
3362         pure nothrow @nogc unittest{
3363             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3364 
3365             assert(vec.ptr[0 .. 3] == [1, 2, 3]);
3366         }
3367 
3368         //Vector.elements
3369         pure nothrow @nogc unittest{
3370             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3371 
3372             int[] slice = vec.elements;
3373             assert(slice.length == vec.length);
3374             assert(slice.ptr is vec.ptr);
3375 
3376             const size_t old_capacity = vec.capacity;
3377             vec.reserve(max(2, vec.capacity * 2));
3378             assert(vec.capacity != old_capacity);
3379             assert(slice.length == vec.length);
3380             // slice contains dangling pointer!
3381         }
3382 
3383         //Vector.front
3384         pure nothrow @nogc @system unittest{
3385             auto vec = Vector!(int, 10).build(1, 2, 3);
3386 
3387             assert(vec.front == 1);
3388         }
3389 
3390         //Vector.frontCopy
3391         pure nothrow @nogc @safe unittest{
3392             auto vec = Vector!(int, 10).build(1, 2, 3);
3393 
3394             assert(vec.frontCopy == 1);
3395             assert(vec == [1, 2, 3]);
3396         }
3397 
3398         //Vector.moveFront
3399         pure nothrow @nogc @safe unittest{
3400             auto vec = Vector!(int, 10).build(1, 2, 3);
3401 
3402             assert(vec.moveFront == 1);
3403             assert(vec == [1, 2, 3]);
3404         }
3405 
3406         //Vector.back
3407         pure nothrow @nogc @system unittest{
3408             auto vec = Vector!(int, 10).build(1, 2, 3);
3409 
3410             assert(vec.back == 3);
3411         }
3412 
3413         //Vector.backCopy
3414         pure nothrow @nogc @safe unittest{
3415             auto vec = Vector!(int, 10).build(1, 2, 3);
3416 
3417             assert(vec.backCopy == 3);
3418             assert(vec == [1, 2, 3]);
3419         }
3420 
3421         //Vector.moveBack
3422         pure nothrow @nogc @safe unittest{
3423             auto vec = Vector!(int, 10).build(1, 2, 3);
3424 
3425             assert(vec.moveBack == 3);
3426             assert(vec == [1, 2, 3]);
3427         }
3428 
3429 
3430         //Vector.popBack
3431         pure nothrow @nogc @safe unittest{
3432             Vector!(int, 6) vec = Vector!(int, 6).build(10, 20, 30);
3433             assert(vec.length == 3);
3434 
3435             assert(vec.popBack == 30);
3436             assert(vec.length == 2);
3437 
3438             assert(vec.popBack == 20);
3439             assert(vec.length == 1);
3440 
3441             assert(vec.popBack == 10);
3442             assert(vec.empty);
3443 
3444             assert(vec.popBack == int.init);
3445             assert(vec.empty);
3446         }
3447 
3448         //Vector.pop
3449         pure nothrow @nogc @safe unittest{
3450             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5);
3451             assert(vec.length == 5);
3452 
3453             assert(vec.pop(0) == 1);
3454             assert(vec == [2, 3, 4, 5]);
3455 
3456             assert(vec.pop(3) == 5);
3457             assert(vec == [2, 3, 4]);
3458 
3459             assert(vec.pop(1) == 3);
3460             assert(vec == [2, 4]);
3461         }
3462 
3463         //Vector.clear
3464         pure nothrow @nogc @safe unittest{
3465             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3466 
3467             vec.reserve(vec.capacity * 2);
3468             assert(vec.length == 3);
3469 
3470             const size_t cap = vec.capacity;
3471             vec.clear();
3472             assert(vec.capacity == cap);
3473         }
3474 
3475         //Vector.release
3476         pure nothrow @nogc @safe unittest{
3477             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3478 
3479             vec.reserve(vec.capacity * 2);
3480             assert(vec.length == 3);
3481 
3482             const size_t cap = vec.capacity;
3483             vec.clear();
3484             assert(vec.capacity == cap);
3485 
3486             vec.release();
3487             assert(vec.capacity == typeof(vec).minimalCapacity);
3488             assert(vec.capacity < cap);
3489         }
3490 
3491         //Vector.reserve
3492         pure nothrow @nogc @safe unittest{
3493             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3494 
3495             const size_t old_capacity = vec.capacity;//assert(vec.capacity == typeof(vec).minimalCapacity);
3496             const size_t cap = (vec.capacity * 2);
3497 
3498             vec.reserve(cap);
3499             assert(vec.capacity > old_capacity);
3500             assert(vec.capacity >= cap);
3501         }
3502 
3503         //Vector.resize
3504         pure nothrow @nogc @safe unittest{
3505             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3506 
3507             vec.resize(5, 0);
3508             assert(vec == [1, 2, 3, 0, 0]);
3509 
3510             vec.resize(2);
3511             assert(vec == [1, 2]);
3512         }
3513 
3514         //Vector.downsize
3515         pure nothrow @nogc @safe unittest{
3516             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3517 
3518             vec.downsize(5);
3519             assert(vec == [1, 2, 3]);
3520 
3521             vec.downsize(2);
3522             assert(vec == [1, 2]);
3523         }
3524 
3525         //Vector.upsize
3526         pure nothrow @nogc @safe unittest{
3527             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3528 
3529             vec.upsize(5, 0);
3530             assert(vec == [1, 2, 3, 0, 0]);
3531 
3532             vec.upsize(2);
3533             assert(vec == [1, 2, 3, 0, 0]);
3534         }
3535 
3536         //Vector.shrinkToFit
3537         pure nothrow @nogc @safe unittest{
3538             auto vec = Vector!(int, 3).build(1, 2, 3);
3539 
3540 
3541             assert(vec.capacity == vec.length);
3542 
3543             vec.reserve(vec.capacity * 2);
3544             assert(vec.capacity > vec.length);
3545 
3546             static if(typeof(vec).minimalCapacity != 0){
3547                 vec.shrinkToFit();
3548                 assert(vec.capacity == vec.length);
3549             }
3550         }
3551 
3552         //Vector._ctor
3553         pure nothrow @nogc @safe unittest{
3554             {
3555                 Vector!(int, 6) vec = null;
3556                 assert(vec.empty);
3557             }
3558 
3559             {
3560                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2);
3561                 assert(vec == [1, 2]);
3562             }
3563 
3564             {
3565                 auto tmp = Vector!(int, 6).build(1, 2);
3566                 Vector!(int, 6) vec = tmp;
3567                 assert(vec == [1, 2]);
3568             }
3569 
3570 
3571             {
3572                 Vector!(int, 6) vec = Vector!(int, 4).build(1, 2);
3573                 assert(vec == [1, 2]);
3574             }
3575 
3576             {
3577                 auto tmp = Vector!(int, 4).build(1, 2);
3578                 Vector!(int, 6) vec = tmp;
3579                 assert(vec == [1, 2]);
3580             }
3581 
3582             {
3583                 int[3] tmp = [1, 2, 3];
3584                 Vector!(int, 6) vec = tmp[];
3585                 assert(vec == [1, 2, 3]);
3586             }
3587 
3588             {
3589                 struct Range{
3590                     int i;
3591 
3592                     bool empty()(){return i == 0;}
3593                     int front()(){return i;}
3594                     void popFront()(){i -= 1;}
3595                     //size_t length(); //no length
3596                 }
3597 
3598                 Vector!(int, 6) vec = Range(3);
3599                 assert(vec == [3, 2, 1]);
3600             }
3601         }
3602 
3603         //Vector.opAssign
3604         pure nothrow @nogc @safe unittest{
3605             {
3606                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3607                 assert(!vec.empty);
3608 
3609                 vec = null;
3610                 assert(vec.empty);
3611 
3612                 vec = Vector!(int, 42).build(3, 2, 1);
3613                 assert(vec == [3, 2, 1]);
3614 
3615                 vec = Vector!(int, 2).build(4, 2);
3616                 assert(vec == [4, 2]);
3617             }
3618 
3619             {
3620                 Vector!(int, 6) vec = null;
3621                 int[3] tmp = [1, 2, 3];
3622                 vec = tmp[];
3623                 assert(vec == [1, 2, 3]);
3624             }
3625 
3626             {
3627                 struct Range{
3628                     int i;
3629 
3630                     bool empty()(){return i == 0;}
3631                     int front()(){return i;}
3632                     void popFront()(){i -= 1;}
3633                     //size_t length(); //no length
3634                 }
3635 
3636                 Vector!(int, 6) vec = null;
3637                 vec = Range(3);
3638                 assert(vec == [3, 2, 1]);
3639             }
3640         }
3641 
3642         //Vector.contains
3643         pure nothrow @nogc @safe unittest{
3644             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3645 
3646             assert(vec.contains(1));
3647             assert(!vec.contains(42L));
3648         }
3649 
3650         //Vector.opBinaryRight!"in"
3651         pure nothrow @nogc @safe unittest{
3652             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3653 
3654             assert(1 in vec);
3655             assert(42L !in vec);
3656         }
3657 
3658         //Vector.opEquals
3659         pure nothrow @nogc @safe unittest{
3660             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3661 
3662             assert(vec != null);
3663             assert(null != vec);
3664 
3665             assert(vec == [1, 2, 3]);
3666             assert([1, 2, 3] == vec);
3667 
3668             assert(vec == typeof(vec).build(1, 2, 3));
3669             assert(typeof(vec).build(1, 2, 3) == vec);
3670 
3671 
3672             import std.range : only;
3673             assert(vec == only(1, 2, 3));
3674             assert(only(1, 2, 3) == vec);
3675         }
3676 
3677         //Vector.opCmp
3678         pure nothrow @nogc @safe unittest{
3679             auto a1 = Vector!(int, 6).build(1, 2, 3);
3680             auto a2 = Vector!(int, 6).build(1, 2, 3, 4);
3681             auto b = Vector!(int, 6).build(3, 2, 1);
3682 
3683             assert(a1 < b);
3684             assert(a1 < a2);
3685             assert(a2 < b);
3686             assert(a1 <= a1);
3687         }
3688 
3689         //Vector.opIndexAssign
3690         pure nothrow @nogc @safe unittest{
3691 
3692             {
3693                 auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
3694 
3695                 vec[1] = 42;
3696 
3697                 assert(vec == [1, 42, 3, 4, 5]);
3698             }
3699 
3700             {
3701                 auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
3702 
3703                 vec[1 .. $-1] = 42;
3704 
3705                 assert(vec == [1, 42, 42, 42, 5]);
3706             }
3707         }
3708 
3709         //Vector.opIndexOpAssign
3710         pure nothrow @nogc @safe unittest{
3711             {
3712                 auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
3713 
3714                 vec[1] += 40;
3715 
3716                 assert(vec == [1, 42, 3, 4, 5]);
3717             }
3718 
3719             {
3720                 auto vec = Vector!(int, 4).build(1, 2, 3, 4, 5);
3721 
3722                 vec[1 .. $-1] *= -1;
3723 
3724                 assert(vec == [1, -2, -3, -4, 5]);
3725             }
3726         }
3727 
3728         //Vector.opIndex()
3729         pure nothrow @nogc @system unittest{
3730             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3);
3731 
3732             scope int[] slice = vec[];
3733             assert(slice.length == vec.length);
3734             assert(slice.ptr is vec.ptr);
3735 
3736             vec.reserve(vec.capacity * 2);
3737             assert(slice.length == vec.length);
3738             // slice contains dangling pointer!
3739         }
3740 
3741         //Vector.opSlice(begin, end)
3742         pure nothrow @nogc @system unittest{
3743             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
3744 
3745             assert(vec[1 .. 4] == [2, 3, 4]);
3746             assert(vec[1 .. $] == [2, 3, 4, 5, 6]);
3747         }
3748 
3749         //Vector.opIndex
3750         pure nothrow @nogc @system unittest{
3751             auto vec = Vector!(int, 10).build(1, 2, 3);
3752 
3753             assert(vec[1] == 2);
3754         }
3755 
3756         //Vector.at
3757         pure nothrow @nogc @system unittest{
3758             auto vec = Vector!(int, 10).build(1, 2, 3);
3759 
3760             assert(vec.at(1) == 2);
3761         }
3762 
3763         //Vector.atCopy
3764         pure nothrow @nogc @safe unittest{
3765             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
3766 
3767             assert(vec.atCopy(3) == 4);
3768             assert(vec.atCopy(vec.length-1) == 6);
3769 
3770         }
3771 
3772         //Vector.proxySwap
3773         pure nothrow @nogc @system unittest{
3774             auto a = Vector!(int, 6).build(1, 2, 3);
3775             auto b = Vector!(int, 6).build(4, 5, 6, 7);
3776 
3777             a.proxySwap(b);
3778             assert(a == [4, 5, 6, 7]);
3779             assert(b == [1, 2, 3]);
3780 
3781             import std.algorithm.mutation : swap;
3782 
3783             swap(a, b);
3784             assert(a == [1, 2, 3]);
3785             assert(b == [4, 5, 6, 7]);
3786         }
3787 
3788 
3789         //Vector.emplace
3790         pure nothrow @nogc @system unittest{
3791             {
3792                 auto vec = Vector!(int, 6).build(1, 2, 3);
3793 
3794                 vec.emplace(1, 42);
3795                 //debug writeln(vec[]);
3796                 assert(vec == [1, 42, 2, 3]);
3797 
3798                 vec.emplace(4, 314);
3799                 assert(vec == [1, 42, 2, 3, 314]);
3800 
3801                 vec.emplace(100, -1);
3802                 assert(vec == [1, 42, 2, 3, 314, -1]);
3803             }
3804 
3805             {
3806                 auto vec = Vector!(int, 6).build(1, 2, 3);
3807 
3808                 vec.emplace(vec.ptr + 1, 42);
3809                 assert(vec == [1, 42, 2, 3]);
3810 
3811                 vec.emplace(vec.ptr + 4, 314);
3812                 assert(vec == [1, 42, 2, 3, 314]);
3813 
3814                 vec.emplace(vec.ptr + 100, -1);
3815                 assert(vec == [1, 42, 2, 3, 314, -1]);
3816             }
3817 
3818             {
3819                 static struct Foo{
3820                     int i;
3821                     string str;
3822                 }
3823 
3824                 auto vec = Vector!(Foo, 6).build(Foo(1, "A"));
3825 
3826                 vec.emplace(1, 2, "B");
3827                 assert(vec == only(Foo(1, "A"), Foo(2, "B")));
3828 
3829                 vec.emplace(0, 42, "X");
3830                 assert(vec == only(Foo(42, "X"), Foo(1, "A"), Foo(2, "B")));
3831             }
3832         }
3833 
3834 
3835         //Vector.emplaceBack
3836         pure nothrow @nogc @system unittest{
3837             {
3838                 auto vec = Vector!(int, 6).build(1, 2, 3);
3839 
3840                 vec.emplaceBack(42);
3841                 assert(vec == [1, 2, 3, 42]);
3842 
3843                 vec.emplaceBack();
3844                 assert(vec == [1, 2, 3, 42, 0]);
3845             }
3846 
3847             {
3848                 static struct Foo{
3849                     int i;
3850                     string str;
3851                 }
3852 
3853                 auto vec = Vector!(Foo, 6).build(Foo(1, "A"));
3854 
3855                 vec.emplaceBack(2, "B");
3856                 assert(vec == only(Foo(1, "A"), Foo(2, "B")));
3857             }
3858         }
3859 
3860         //Vector.append
3861         pure nothrow @nogc @system unittest{
3862             {
3863                 auto vec = Vector!(int, 6).build(1, 2, 3);
3864 
3865                 vec.append(42);
3866                 assert(vec == [1, 2, 3, 42]);
3867             }
3868 
3869             {
3870                 auto vec = Vector!(int, 6).build(1, 2, 3);
3871 
3872                 vec.append(only(4, 5, 6));
3873                 assert(vec == [1, 2, 3, 4, 5, 6]);
3874             }
3875 
3876             {
3877                 auto a = Vector!(int, 6).build(1, 2, 3);
3878                 auto b = Vector!(int, 6).build(4, 5, 6);
3879 
3880                 a.append(b);
3881                 assert(a == [1, 2, 3, 4, 5, 6]);
3882             }
3883 
3884             {
3885                 Vector!(int, 3) vec = Vector!(int, 3).build(1, 2, 3);
3886                 int[3] tmp = [4, 5, 6];
3887                 vec.append(tmp[]);
3888                 assert(vec == [1, 2, 3, 4, 5, 6]);
3889             }
3890 
3891             {
3892                 struct Range{
3893                     int i;
3894 
3895                     bool empty()(){return i == 0;}
3896                     int front()(){return i;}
3897                     void popFront()(){i -= 1;}
3898                     //size_t length(); //no length
3899                 }
3900 
3901                 Vector!(int, 3) vec = Vector!(int, 3).build(6, 5, 4);
3902                 vec.append(Range(3));
3903                 assert(vec == [6, 5, 4, 3, 2, 1]);
3904             }
3905 
3906         }
3907 
3908         //Vector.insert
3909         pure nothrow @nogc @system unittest{
3910             //pos:
3911             {
3912                 auto vec = Vector!(int, 3).build(1, 2, 3);
3913 
3914                 size_t pos = vec.insert(1, 42, 2);
3915                 assert(pos == 1);
3916                 assert(vec == [1, 42, 42, 2, 3]);
3917 
3918                 pos = vec.insert(100, 4, 3);
3919                 assert(pos == 5);
3920                 assert(vec == [1, 42, 42, 2, 3, 4, 4, 4]);
3921             }
3922 
3923             {
3924                 auto vec = Vector!(int, 3).build(1, 2, 3);
3925 
3926                 size_t pos = vec.insert(1, only(20, 30, 40));
3927                 assert(pos == 1);
3928                 assert(vec == [1, 20, 30, 40, 2, 3]);
3929 
3930                 pos = vec.insert(100, only(4, 5, 6));
3931                 assert(pos == 6);
3932                 assert(vec == [1, 20, 30, 40, 2, 3, 4, 5, 6]);
3933             }
3934 
3935             {
3936                 auto vec = Vector!(int, 3).build(1, 2, 3);
3937                 auto tmp = Vector!(int, 10).build(-1, -2, -3);
3938 
3939                 size_t pos = vec.insert(1, tmp);
3940                 assert(pos == 1);
3941                 assert(vec == [1, -1, -2, -3, 2, 3]);
3942 
3943                 pos = vec.insert(100, Vector!(int, 10).build(40, 50, 60));
3944                 assert(pos == 6);
3945                 assert(vec == [1, -1, -2, -3, 2, 3, 40, 50, 60]);
3946             }
3947 
3948             //ptr:
3949             {
3950                 auto vec = Vector!(int, 3).build(1, 2, 3);
3951 
3952                 size_t pos = vec.insert(vec.ptr + 1, 42, 2);
3953                 assert(pos == 1);
3954                 assert(vec == [1, 42, 42, 2, 3]);
3955 
3956                 pos = vec.insert(vec.ptr + 100, 4, 3);
3957                 assert(pos == 5);
3958                 assert(vec == [1, 42, 42, 2, 3, 4, 4, 4]);
3959             }
3960 
3961             {
3962                 auto vec = Vector!(int, 3).build(1, 2, 3);
3963 
3964                 size_t pos = vec.insert(vec.ptr + 1, only(20, 30, 40));
3965                 assert(pos == 1);
3966                 assert(vec == [1, 20, 30, 40, 2, 3]);
3967 
3968                 pos = vec.insert(vec.ptr + 100, only(4, 5, 6));
3969                 assert(pos == 6);
3970                 assert(vec == [1, 20, 30, 40, 2, 3, 4, 5, 6]);
3971             }
3972 
3973             {
3974                 auto vec = Vector!(int, 3).build(1, 2, 3);
3975                 auto tmp = Vector!(int, 10).build(-1, -2, -3);
3976 
3977                 size_t pos = vec.insert(vec.ptr + 1, tmp);
3978                 assert(pos == 1);
3979                 assert(vec == [1, -1, -2, -3, 2, 3]);
3980 
3981                 pos = vec.insert(vec.ptr + 100, Vector!(int, 10).build(40, 50, 60));
3982                 assert(pos == 6);
3983                 assert(vec == [1, -1, -2, -3, 2, 3, 40, 50, 60]);
3984             }
3985         }
3986 
3987         //Vector.erase
3988         pure nothrow @nogc @system unittest{
3989             //pos:
3990             {
3991                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
3992 
3993                 size_t pos = vec.erase(3);
3994                 assert(pos == 3);
3995                 assert(vec == [1, 2, 3]);
3996 
3997                 pos = vec.erase(100);
3998                 assert(pos == 3);
3999                 assert(vec == [1, 2, 3]);
4000             }
4001 
4002             {
4003                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4004 
4005                 size_t pos = vec.erase(1, 4);
4006                 assert(pos == 1);
4007                 assert(vec == [1, 6]);
4008 
4009                 pos = vec.erase(100, 4);
4010                 assert(pos == 2);
4011                 assert(vec == [1, 6]);
4012 
4013                 pos = vec.erase(0, 100);
4014                 assert(pos == 0);
4015                 assert(vec.empty);
4016             }
4017 
4018             //ptr:
4019             {
4020                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4021 
4022                 size_t pos = vec.erase(vec.ptr + 3);
4023                 assert(pos == 3);
4024                 assert(vec == [1, 2, 3]);
4025 
4026                 pos = vec.erase(vec.ptr + 100);
4027                 assert(pos == 3);
4028                 assert(vec == [1, 2, 3]);
4029             }
4030 
4031             {
4032                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4033 
4034                 size_t pos = vec.erase(vec[1 .. 5]);
4035                 assert(pos == 1);
4036                 assert(vec == [1, 6]);
4037             }
4038         }
4039 
4040         //Vector.replace
4041         pure nothrow @nogc @system unittest{
4042             //pos:
4043             {
4044                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4045 
4046                 size_t pos = vec.replace(2, 2, 0, 5);
4047                 assert(pos == 2);
4048                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4049 
4050                 pos = vec.replace(100, 2, 42, 2);
4051                 assert(pos == 9);
4052                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4053 
4054                 pos = vec.replace(2, 100, -1);
4055                 assert(pos == 2);
4056                 assert(vec == [1, 2,  -1]);
4057             }
4058 
4059             {
4060                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4061 
4062                 size_t pos = vec.replace(2, 2, only(0, 0, 0, 0, 0));
4063                 assert(pos == 2);
4064                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4065 
4066                 pos = vec.replace(100, 2, only(42, 42));
4067                 assert(pos == 9);
4068                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4069 
4070                 pos = vec.replace(2, 100, only(-1));
4071                 assert(pos == 2);
4072                 assert(vec == [1, 2,  -1]);
4073             }
4074 
4075             {
4076                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4077 
4078                 size_t pos = vec.replace(2, 2, Vector!(int, 3).build(0, 0, 0, 0, 0));
4079                 assert(pos == 2);
4080                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4081 
4082                 pos = vec.replace(100, 2, Vector!(int, 2).build(42, 42));
4083                 assert(pos == 9);
4084                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4085 
4086                 pos = vec.replace(2, 100, Vector!(int, 2).build(-1));
4087                 assert(pos == 2);
4088                 assert(vec == [1, 2,  -1]);
4089             }
4090 
4091             //ptr:
4092             {
4093                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4094 
4095                 size_t pos = vec.replace(vec[2 .. 4], 0, 5);
4096                 assert(pos == 2);
4097                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4098 
4099                 pos = vec.replace(vec.ptr[100 .. 102], 42, 2);
4100                 assert(pos == 9);
4101                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4102 
4103                 pos = vec.replace(vec.ptr[2 .. 100], -1);
4104                 assert(pos == 2);
4105                 assert(vec == [1, 2,  -1]);
4106             }
4107 
4108             {
4109                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4110 
4111                 size_t pos = vec.replace(vec[2 .. 4], only(0, 0, 0, 0, 0));
4112                 assert(pos == 2);
4113                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4114 
4115                 pos = vec.replace(vec.ptr[100 .. 102], only(42, 42));
4116                 assert(pos == 9);
4117                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4118 
4119                 pos = vec.replace(vec.ptr[2 .. 100], only(-1));
4120                 assert(pos == 2);
4121                 assert(vec == [1, 2,  -1]);
4122             }
4123 
4124             {
4125                 auto vec = Vector!(int, 3).build(1, 2, 3, 4, 5, 6);
4126 
4127                 size_t pos = vec.replace(vec[2 .. 4], Vector!(int, 3).build(0, 0, 0, 0, 0));
4128                 assert(pos == 2);
4129                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6]);
4130 
4131                 pos = vec.replace(vec.ptr[100 .. 102], Vector!(int, 2).build(42, 42));
4132                 assert(pos == 9);
4133                 assert(vec == [1, 2,  0, 0, 0, 0, 0,  5, 6,  42, 42]);
4134 
4135                 pos = vec.replace(vec.ptr[2 .. 100], Vector!(int, 2).build(-1));
4136                 assert(pos == 2);
4137                 assert(vec == [1, 2,  -1]);
4138             }
4139         }
4140 
4141         //Vector.owns
4142         pure nothrow @nogc @system unittest{
4143             Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
4144 
4145             {
4146                 assert(vec.owns(vec.ptr + 3));
4147                 assert(!vec.owns(cast(int*)null));
4148                 assert(!vec.owns(vec.ptr + 100));
4149             }
4150 
4151             {
4152                 assert(vec.owns(&vec[$-1]));
4153                 assert(!vec.owns(cast(long*)&vec[$-1]));
4154             }
4155         }
4156 
4157         //Vector.ownsElement
4158         pure nothrow @nogc @system unittest{
4159                 Vector!(int, 6) vec = Vector!(int, 6).build(1, 2, 3, 4, 5, 6);
4160 
4161                 {
4162                     assert(vec.ownsElement(vec.ptr + 3));
4163                     assert(!vec.ownsElement(cast(int*)null));
4164                     assert(!vec.ownsElement(vec.ptr + 100));
4165                 }
4166 
4167                 {
4168                     const int* p = cast(int*)((cast(byte*)vec.ptr) + 1);
4169                     assert(vec.owns(p));
4170                     assert(!vec.ownsElement(p));
4171                 }
4172         }
4173 
4174         //Vector.build
4175         pure nothrow @nogc @safe unittest{
4176             import std.range : only;
4177 
4178             auto vec = Vector!(int, 6).build(1, 2, only(3, 4), only(5, 6), Vector!(int, 10).build(7, 8));
4179             assert(vec == [1, 2, 3, 4, 5, 6, 7, 8]);
4180         }
4181     }
4182 }
4183 
4184 
4185 //ctors + assign tests:
4186 version(unittest){
4187     struct Foo{
4188 
4189         static class Counter{
4190             this(char name)pure @safe @nogc nothrow{
4191                 this.name = name;
4192             }
4193             char name;
4194             int objects = 0;
4195             uint ctor;
4196             uint copy;
4197             uint dtor;
4198             uint move_assign;
4199             uint copy_assign;
4200             uint move;
4201         }
4202         private Counter counter;
4203 
4204         //@disable this();
4205 
4206         void opPostMove(const scope ref typeof(this))pure nothrow @safe @nogc{
4207             if(counter)
4208                 counter.move += 1;
4209         }
4210         this(Counter counter)pure nothrow @safe @nogc{
4211             this.counter = counter;
4212             counter.objects += 1;
4213             counter.ctor += 1;
4214         }
4215 
4216         this(ref scope typeof(this) rhs)pure nothrow @safe @nogc{
4217             this.counter = (()@trusted => rhs.counter )();
4218 
4219             if(counter){
4220                 counter.objects += 1;
4221                 counter.copy += 1;
4222             }
4223         }
4224 
4225         ~this()scope pure nothrow @safe @nogc{
4226             if(counter){
4227                 counter.objects -= 1;
4228                 counter.dtor += 1;
4229             }
4230         }
4231 
4232         void opAssign(ref scope typeof(this) rhs)scope pure nothrow @safe @nogc{
4233             this.counter = (()@trusted => rhs.counter )();
4234 
4235             if(counter){
4236                 counter.objects += 1;
4237                 counter.copy_assign += 1;
4238             }
4239         }
4240 
4241         void opAssign(scope typeof(this) rhs)scope pure nothrow @safe @nogc{
4242             this.counter = (()@trusted => *&rhs.counter )();
4243             if(counter){
4244                 counter.move_assign += 1;
4245                 rhs.counter = null;
4246             }
4247         }
4248 
4249 
4250     }
4251 
4252     //ctors:
4253     pure nothrow @safe unittest{
4254         import core.lifetime : move;
4255         import std.range : iota, array;
4256         import std.algorithm : map, all;
4257 
4258         Foo.Counter[3] counters = [new Foo.Counter('A'), new Foo.Counter('B'), new Foo.Counter('C')];
4259 
4260         //small->small
4261         {
4262             //copy
4263             assert(counters[].all!(c => c.objects == 0));
4264             {
4265                 auto vec = Vector!(Foo, 4).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4266                 assert(counters[].all!(c => c.objects == 1));
4267                 assert(vec.small);
4268 
4269                 auto vec2 = vec;
4270                 assert(counters[].all!(c => c.objects == 2));
4271                 assert(vec2.small);
4272             }
4273 
4274             //move
4275             assert(counters[].all!(c => c.objects == 0));
4276             {
4277                 auto vec = Vector!(Foo, 4).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4278                 assert(counters[].all!(c => c.objects == 1));
4279                 assert(vec.small);
4280 
4281                 auto vec2 = move(vec);
4282                 assert(counters[].all!(c => c.objects == 1));
4283                 assert(vec2.small);
4284             }
4285         }
4286 
4287         //large->large
4288         {
4289             //copy
4290             assert(counters[].all!(c => c.objects == 0));
4291             {
4292                 auto vec = Vector!(Foo, 2).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4293                 assert(counters[].all!(c => c.objects == 1));
4294                 assert(!vec.small);
4295 
4296                 auto vec2 = vec;
4297                 assert(counters[].all!(c => c.objects == 2));
4298                 assert(!vec2.small);
4299             }
4300 
4301             //move
4302             assert(counters[].all!(c => c.objects == 0));
4303             {
4304                 auto vec = Vector!(Foo, 2).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4305                 assert(counters[].all!(c => c.objects == 1));
4306                 assert(!vec.small);
4307 
4308                 auto vec2 = move(vec);
4309                 assert(counters[].all!(c => c.objects == 1));
4310                 assert(!vec2.small);
4311             }
4312 
4313         }
4314 
4315 
4316         //large->small
4317         {
4318             //copy
4319             assert(counters[].all!(c => c.objects == 0));
4320             {
4321                 auto vec = Vector!(Foo, 2).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4322                 assert(counters[].all!(c => c.objects == 1));
4323                 assert(!vec.small);
4324 
4325                 Vector!(Foo, 4) vec2 = vec;
4326                 assert(counters[].all!(c => c.objects == 2));
4327                 assert(vec2.small);
4328             }
4329 
4330             //move
4331             assert(counters[].all!(c => c.objects == 0));
4332             {
4333                 auto vec = Vector!(Foo, 2).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4334                 assert(counters[].all!(c => c.objects == 1));
4335                 assert(!vec.small);
4336 
4337                 //debug writeln("-----");
4338                 Vector!(Foo, 4) vec2 = move(vec);
4339                 assert(counters[].all!(c => c.objects == 1));
4340                 //debug writeln(vec2.length, ", ", vec2.capacity, ", ", vec2.minimalCapacity);
4341                 assert(vec2.small);
4342             }
4343 
4344         }
4345 
4346 
4347         //small->large
4348         {
4349             //copy
4350             assert(counters[].all!(c => c.objects == 0));
4351             {
4352                 auto vec = Vector!(Foo, 4).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4353                 assert(counters[].all!(c => c.objects == 1));
4354                 assert(vec.small);
4355 
4356                 Vector!(Foo, 2) vec2 = vec;
4357                 assert(counters[].all!(c => c.objects == 2));
4358                 assert(!vec2.small);
4359             }
4360 
4361             //move
4362             assert(counters[].all!(c => c.objects == 0));
4363             {
4364                 auto vec = Vector!(Foo, 4).build(iota(0, 3, 1).map!(x => Foo(counters[x])));
4365                 assert(counters[].all!(c => c.objects == 1));
4366                 assert(vec.small);
4367 
4368                 Vector!(Foo, 2) vec2 = move(vec);
4369                 assert(counters[].all!(c => c.objects == 1));
4370                 assert(!vec2.small);
4371             }
4372         }
4373 
4374 
4375     }
4376 
4377     //assign:
4378     pure nothrow @safe unittest{
4379         //TODO
4380     }
4381 
4382 
4383     //simple rvalue ctor:
4384     pure nothrow @safe @nogc unittest{
4385         import core.lifetime : move;
4386         {
4387             auto vec = Vector!(int, 4).build(1, 2, 3);
4388             assert(vec.small);
4389 
4390             auto vec2 = move(vec);
4391             assert(vec2.small);
4392 
4393 
4394             //assert(vec2 == [1, 2, 3]);
4395             assert(vec.empty);
4396 
4397         }
4398 
4399         {
4400             auto vec = Vector!(int, 4).build(1, 2, 3);
4401             assert(vec.small);
4402 
4403             Vector!(int, 2) vec2 = move(vec);
4404             assert(!vec2.small);
4405 
4406             assert(vec2 == [1, 2, 3]);
4407             assert(vec.empty);
4408         }
4409 
4410         {
4411             auto vec = Vector!(int, 2).build(1, 2, 3);
4412             assert(!vec.small);
4413 
4414             Vector!(int, 2) vec2 = move(vec);
4415             assert(!vec2.small);
4416 
4417             assert(vec2 == [1, 2, 3]);
4418             assert(vec.empty);
4419         }
4420 
4421         {
4422             auto vec = Vector!(int, 2).build(1, 2, 3);
4423             assert(!vec.small);
4424 
4425             Vector!(int, 4) vec2 = move(vec);
4426             assert(vec2.small);
4427 
4428             assert(vec2 == [1, 2, 3]);
4429             assert(vec.empty);
4430         }
4431     }
4432 
4433     //simple lvalue ctor:
4434     pure nothrow @safe @nogc unittest{
4435         import core.lifetime : move;
4436         {
4437             auto vec = Vector!(int, 4).build(1, 2, 3);
4438             auto vec2 = vec;
4439 
4440             assert(vec.small && vec2.small);
4441 
4442             assert(vec2 == [1, 2, 3]);
4443             assert(vec == [1, 2, 3]);
4444         }
4445 
4446         {
4447             auto vec = Vector!(int, 4).build(1, 2, 3);
4448             Vector!(int, 2) vec2 = vec;
4449 
4450             assert(vec.small && !vec2.small);
4451 
4452             assert(vec2 == [1, 2, 3]);
4453             assert(vec == [1, 2, 3]);
4454         }
4455 
4456         {
4457             auto vec = Vector!(int, 2).build(1, 2, 3);
4458             Vector!(int, 2) vec2 = vec;
4459 
4460             assert(!vec.small && !vec2.small);
4461 
4462             assert(vec2 == [1, 2, 3]);
4463             assert(vec == [1, 2, 3]);
4464         }
4465 
4466         {
4467             auto vec = Vector!(int, 2).build(1, 2, 3);
4468             Vector!(int, 4) vec2 = vec;
4469 
4470             assert(!vec.small && vec2.small);
4471 
4472             assert(vec2 == [1, 2, 3]);
4473             assert(vec == [1, 2, 3]);
4474         }
4475     }
4476 
4477 }
4478 
4479 //opAssign tests:
4480 version(unittest){
4481     //TODO
4482 
4483 }
4484 
4485 
4486 //swap tests:
4487 version(unittest){
4488 
4489     pure nothrow @safe @nogc unittest{
4490         auto small = Vector!(int, 4).build(1, 2);
4491         auto large = Vector!(int, 4).build(10, 20, 30, 40, 50, 60, 70);
4492 
4493         assert(small.small == true);
4494         assert(large.small == false);
4495 
4496         small.proxySwap(large);
4497         assert(small == [10, 20, 30, 40, 50, 60, 70]);
4498         assert(large == [1, 2]);
4499 
4500 
4501         assert(small.small == false);
4502         assert(large.small == true);
4503     }
4504 
4505     pure nothrow @safe @nogc unittest{
4506         auto a = Vector!(int, 4).build(1, 2);
4507         auto b = Vector!(int, 4).build(3, 4);
4508 
4509         assert(a.small == true);
4510         assert(b.small == true);
4511 
4512         a.proxySwap(b);
4513         assert(a == [3, 4]);
4514         assert(b == [1, 2]);
4515 
4516         assert(a.small == true);
4517         assert(b.small == true);
4518     }
4519 
4520     pure nothrow @safe @nogc unittest{
4521         auto a = Vector!(int, 4).build(1, 2, 3, 4, 5, 6, 7);
4522         auto b = Vector!(int, 4).build(10, 20, 30, 40, 50, 60, 70);
4523 
4524         assert(a.small == false);
4525         assert(b.small == false);
4526 
4527         a.proxySwap(b);
4528         assert(a == [10, 20, 30, 40, 50, 60, 70]);
4529         assert(b == [1, 2, 3, 4, 5, 6, 7]);
4530 
4531         assert(a.small == false);
4532         assert(b.small == false);
4533     }
4534 
4535 
4536 }
4537 
4538 //version
4539 version(unittest){
4540     private import btl.internal.test_allocator;
4541 
4542     nothrow unittest{
4543         TestAllocator* allcoator = new TestAllocator;
4544 
4545         auto vec = Vector!(int, 2, TestAllocator*)(allcoator);
4546 
4547         assert(allcoator.get_count == 0);
4548 
4549         vec.append([1, 2, 3, 4, 5, 6]);
4550         assert(allcoator.get_count == 1);
4551 
4552         auto vec2 = vec;
4553         assert(allcoator.get_count == 2);
4554 
4555         vec.release();
4556         assert(allcoator.get_count == 1);
4557 
4558         vec2.release();
4559         assert(allcoator.get_count == 0);
4560     }
4561 
4562 }
4563 
4564 
4565 //.md example
4566 pure nothrow @nogc unittest{
4567     import std.range : only;
4568     import std.algorithm : map, equal;
4569 
4570     static struct Foo{
4571         int i;
4572         string str;
4573     }
4574 
4575     Vector!(Foo, 4) vec;
4576 
4577     assert(vec.empty);
4578     assert(vec.capacity == 4);
4579     assert(typeof(vec).minimalCapacity == 4);
4580 
4581     vec.append(Foo(1, "A"));
4582     assert(vec.length == 1);
4583 
4584     vec.append(only(Foo(2, "B"), Foo(3, "C")));
4585     assert(vec.length == 3);
4586 
4587     vec.emplaceBack(4, "D");
4588     assert(vec.length == 4);
4589     assert(vec.capacity == 4);
4590 
4591     vec.insert(1, Foo(5, "E"));
4592     assert(vec.length == 5);
4593     assert(vec.capacity > 4);
4594     assert(equal(vec[].map!(e => e.str), only("A", "E", "B", "C", "D")));
4595 
4596     vec.erase(vec[1 .. $-1]);   //same as vec.erase(1, 3);
4597     assert(vec == only(Foo(1, "A"), Foo(4, "D")));
4598 
4599 
4600     vec.clear();
4601     assert(vec.length == 0);
4602     assert(vec.capacity > 4);
4603 
4604     vec.release();
4605     assert(vec.length == 0);
4606     assert(vec.capacity == typeof(vec).minimalCapacity);
4607 
4608     vec = Vector!(Foo, 4).build(Foo(-1, "X"), Foo(-2, "Y"));
4609     assert(equal(vec[].map!(e => e.str), only("X", "Y")));
4610 
4611 }
4612 
4613 
4614 //opIndexAssign
4615 @safe pure nothrow @nogc unittest{
4616     auto vec = Vector!int.build(1, 2, 3);
4617 
4618     vec[0] = -1;
4619     assert(vec == [-1, 2, 3]);
4620 
4621     vec[1 .. $] = -2;
4622     assert(vec == [-1, -2, -2]);
4623 
4624     vec[0] *= -1;
4625     assert(vec == [1, -2, -2]);
4626 
4627     vec[1 .. $] *= -1;
4628     assert(vec == [1, 2, 2]);
4629 }
4630 
4631