1 // Written in the D programming language. 2 3 /** 4 This module defines generic containers. 5 6 $(H3 $(LNAME2 construction, Construction)) 7 8 To implement the different containers, both struct and class based 9 approaches have been used. $(REF make, std,container,util) allows for 10 uniform construction with either approach. 11 12 $(RUNNABLE_EXAMPLE 13 --- 14 import std.container; 15 // Construct a red-black tree and an array both containing the values 1, 2, 3. 16 // RedBlackTree should typically be allocated using `new` 17 RedBlackTree!int rbTree = new RedBlackTree!int(1, 2, 3); 18 // But `new` should not be used with Array 19 Array!int array = Array!int(1, 2, 3); 20 21 // `make` hides the differences 22 RedBlackTree!int rbTree2 = make!(RedBlackTree!int)(1, 2, 3); 23 Array!int array2 = make!(Array!int)(1, 2, 3); 24 25 assert(rbTree == rbTree2); 26 assert(array == array2); 27 --- 28 ) 29 30 Note that `make` can infer the element type from the given arguments. 31 32 --- 33 import std.container; 34 35 auto rbTree = make!RedBlackTree(1, 2, 3); // RedBlackTree!int 36 auto array = make!Array("1", "2", "3"); // Array!string 37 --- 38 39 $(H3 $(LNAME2 reference-semantics, Reference Semantics)) 40 41 All containers have reference semantics, which means that after 42 assignment both variables refer to the same underlying data. 43 44 To make a copy of a container, use the `c.dup` container primitive. 45 46 $(RUNNABLE_EXAMPLE 47 --- 48 import std.algorithm, std.container, std.range; 49 50 Array!int originalArray = make!(Array!int)(1, 2, 3); 51 Array!int secondArray = originalArray; 52 assert(equal(originalArray[], secondArray[])); 53 54 // changing one instance changes the other one as well! 55 originalArray[0] = 12; 56 assert(secondArray[0] == 12); 57 58 // secondArray now refers to an independent copy of originalArray 59 secondArray = originalArray.dup; 60 secondArray[0] = 1; 61 // assert that originalArray has not been affected 62 assert(originalArray[0] == 12); 63 --- 64 ) 65 66 $(B Attention:) If the container is implemented as a class, using an 67 uninitialized instance can cause a null pointer dereference. 68 69 --- 70 import std.container; 71 72 RedBlackTree!int rbTree; 73 rbTree.insert(5); // null pointer dereference 74 --- 75 76 Using an uninitialized struct-based container will work, because the struct 77 intializes itself upon use; however, up to this point the container will not 78 have an identity and assignment does not create two references to the same 79 data. 80 81 $(RUNNABLE_EXAMPLE 82 --- 83 import std.container; 84 85 // create an uninitialized array 86 Array!int array1; 87 // array2 does _not_ refer to array1 88 Array!int array2 = array1; 89 array2.insertBack(42); 90 // thus array1 will not be affected 91 assert(array1.empty); 92 93 // after initialization reference semantics work as expected 94 array1 = array2; 95 // now affects array2 as well 96 array1.removeBack(); 97 assert(array2.empty); 98 --- 99 ) 100 101 It is therefore recommended to always construct containers using 102 $(REF make, std,container,util). 103 104 This is in fact necessary to put containers into another container. 105 For example, to construct an `Array` of ten empty `Array`s, use 106 the following that calls `make` ten times. 107 108 --- 109 import std.container, std.range; 110 111 auto arrOfArrs = make!Array(generate!(() => make!(Array!int)).take(10)); 112 --- 113 114 $(H3 $(LNAME2 submodules, Submodules)) 115 116 This module consists of the following submodules: 117 118 $(UL 119 $(LI 120 The $(MREF std, container, array) module provides 121 an array type with deterministic control of memory, not reliant on 122 the GC unlike built-in arrays. 123 ) 124 $(LI 125 The $(MREF std, container, binaryheap) module 126 provides a binary heap implementation that can be applied to any 127 user-provided random-access range. 128 ) 129 $(LI 130 The $(MREF std, container, dlist) module provides 131 a doubly-linked list implementation. 132 ) 133 $(LI 134 The $(MREF std, container, rbtree) module 135 implements red-black trees. 136 ) 137 $(LI 138 The $(MREF std, container, slist) module 139 implements singly-linked lists. 140 ) 141 $(LI 142 The $(MREF std, container, util) module contains 143 some generic tools commonly used by container implementations. 144 ) 145 ) 146 147 $(H3 $(LNAME2 primary-range, The Primary Range of a Container)) 148 149 While some containers offer direct access to their elements e.g. via 150 `opIndex`, `c.front` or `c.back`, access 151 and modification of a container's contents is generally done through 152 its primary $(MREF_ALTTEXT range, std, range) type, 153 which is aliased as `C.Range`. For example, the primary range type of 154 `Array!int` is `Array!int.Range`. 155 156 If the documentation of a member function of a container takes 157 a parameter of type `Range`, then it refers to the primary range type of 158 this container. Oftentimes `Take!Range` will be used, in which case 159 the range refers to a span of the elements in the container. Arguments to 160 these parameters $(B must) be obtained from the same container instance 161 as the one being worked with. It is important to note that many generic range 162 algorithms return the same range type as their input range. 163 164 $(RUNNABLE_EXAMPLE 165 --- 166 import std.algorithm.comparison : equal; 167 import std.algorithm.searching : find; 168 import std.container; 169 import std.range : take; 170 171 auto array = make!Array(1, 2, 3); 172 173 // `find` returns an Array!int.Range advanced to the element "2" 174 array.linearRemove(array[].find(2)); 175 176 assert(array[].equal([1])); 177 178 array = make!Array(1, 2, 3); 179 180 // the range given to `linearRemove` is a Take!(Array!int.Range) 181 // spanning just the element "2" 182 array.linearRemove(array[].find(2).take(1)); 183 184 assert(array[].equal([1, 3])); 185 --- 186 ) 187 188 When any $(MREF_ALTTEXT range, std, range) can be passed as an argument to 189 a member function, the documention usually refers to the parameter's templated 190 type as `Stuff`. 191 192 $(RUNNABLE_EXAMPLE 193 --- 194 import std.algorithm.comparison : equal; 195 import std.container; 196 import std.range : iota; 197 198 auto array = make!Array(1, 2); 199 200 // the range type returned by `iota` is completely unrelated to Array, 201 // which is fine for Array.insertBack: 202 array.insertBack(iota(3, 10)); 203 204 assert(array[].equal([1, 2, 3, 4, 5, 6, 7, 8, 9])); 205 --- 206 ) 207 208 $(H3 $(LNAME2 primitives, Container Primitives)) 209 210 Containers do not form a class hierarchy, instead they implement a 211 common set of primitives (see table below). These primitives each guarantee 212 a specific worst case complexity and thus allow generic code to be written 213 independently of the container implementation. 214 215 For example the primitives `c.remove(r)` and `c.linearRemove(r)` both 216 remove the sequence of elements in range `r` from the container `c`. 217 The primitive `c.remove(r)` guarantees 218 $(BIGOH n$(SUBSCRIPT r) log n$(SUBSCRIPT c)) complexity in the worst case and 219 `c.linearRemove(r)` relaxes this guarantee to $(BIGOH n$(SUBSCRIPT c)). 220 221 Since a sequence of elements can be removed from a $(MREF_ALTTEXT doubly linked list,std,container,dlist) 222 in constant time, `DList` provides the primitive `c.remove(r)` 223 as well as `c.linearRemove(r)`. On the other hand 224 $(MREF_ALTTEXT Array, std,container, array) only offers `c.linearRemove(r)`. 225 226 The following table describes the common set of primitives that containers 227 implement. A container need not implement all primitives, but if a 228 primitive is implemented, it must support the syntax described in the $(B 229 syntax) column with the semantics described in the $(B description) column, and 230 it must not have a worst-case complexity worse than denoted in big-O notation in 231 the $(BIGOH ·) column. Below, `C` means a container type, `c` is 232 a value of container type, $(D n$(SUBSCRIPT x)) represents the effective length of 233 value `x`, which could be a single element (in which case $(D n$(SUBSCRIPT x)) is 234 `1`), a container, or a range. 235 236 $(BOOKTABLE Container primitives, 237 $(TR 238 $(TH Syntax) 239 $(TH $(BIGOH ·)) 240 $(TH Description) 241 ) 242 $(TR 243 $(TDNW `C(x)`) 244 $(TDNW $(D n$(SUBSCRIPT x))) 245 $(TD Creates a container of type `C` from either another container or a range. 246 The created container must not be a null reference even if x is empty.) 247 ) 248 $(TR 249 $(TDNW `c.dup`) 250 $(TDNW $(D n$(SUBSCRIPT c))) 251 $(TD Returns a duplicate of the container.) 252 ) 253 $(TR 254 $(TDNW $(D c ~ x)) 255 $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) 256 $(TD Returns the concatenation of `c` and `r`. `x` may be a single 257 element or an input range.) 258 ) 259 $(TR 260 $(TDNW $(D x ~ c)) 261 $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) 262 $(TD Returns the concatenation of `x` and `c`. `x` may be a 263 single element or an input range type.) 264 ) 265 $(LEADINGROWN 3, Iteration 266 ) 267 $(TR 268 $(TD `c.Range`) 269 $(TD) 270 $(TD The primary range type associated with the container.) 271 ) 272 $(TR 273 $(TD `c[]`) 274 $(TDNW $(D log n$(SUBSCRIPT c))) 275 $(TD Returns a range 276 iterating over the entire container, in a container-defined order.) 277 ) 278 $(TR 279 $(TDNW $(D c[a .. b])) 280 $(TDNW $(D log n$(SUBSCRIPT c))) 281 $(TD Fetches a portion of the container from key `a` to key `b`.) 282 ) 283 $(LEADINGROWN 3, Capacity 284 ) 285 $(TR 286 $(TD `c.empty`) 287 $(TD `1`) 288 $(TD Returns `true` if the container has no elements, `false` otherwise.) 289 ) 290 $(TR 291 $(TD `c.length`) 292 $(TDNW $(D log n$(SUBSCRIPT c))) 293 $(TD Returns the number of elements in the container.) 294 ) 295 $(TR 296 $(TDNW $(D c.length = n)) 297 $(TDNW $(D n$(SUBSCRIPT c) + n)) 298 $(TD Forces the number of elements in the container to `n`. 299 If the container ends up growing, the added elements are initialized 300 in a container-dependent manner (usually with `T.init`).) 301 ) 302 $(TR 303 $(TD `c.capacity`) 304 $(TDNW $(D log n$(SUBSCRIPT c))) 305 $(TD Returns the maximum number of elements that can be stored in the 306 container without triggering a reallocation.) 307 ) 308 $(TR 309 $(TD `c.reserve(x)`) 310 $(TD $(D n$(SUBSCRIPT c))) 311 $(TD Forces `capacity` to at least `x` without reducing it.) 312 ) 313 $(LEADINGROWN 3, Access 314 ) 315 $(TR 316 $(TDNW `c.front`) 317 $(TDNW $(D log n$(SUBSCRIPT c))) 318 $(TD Returns the first element of the container, in a container-defined order.) 319 ) 320 $(TR 321 $(TDNW `c.moveFront`) 322 $(TDNW $(D log n$(SUBSCRIPT c))) 323 $(TD Destructively reads and returns the first element of the 324 container. The slot is not removed from the container; it is left 325 initialized with `T.init`. This routine need not be defined if $(D 326 front) returns a `ref`.) 327 ) 328 $(TR 329 $(TDNW $(D c.front = v)) 330 $(TDNW $(D log n$(SUBSCRIPT c))) 331 $(TD Assigns `v` to the first element of the container.) 332 ) 333 $(TR 334 $(TDNW `c.back`) 335 $(TDNW $(D log n$(SUBSCRIPT c))) 336 $(TD Returns the last element of the container, in a container-defined order.) 337 ) 338 $(TR 339 $(TDNW `c.moveBack`) 340 $(TDNW $(D log n$(SUBSCRIPT c))) 341 $(TD Destructively reads and returns the last element of the 342 container. The slot is not removed from the container; it is left 343 initialized with `T.init`. This routine need not be defined if $(D 344 front) returns a `ref`.) 345 ) 346 $(TR 347 $(TDNW $(D c.back = v)) 348 $(TDNW $(D log n$(SUBSCRIPT c))) 349 $(TD Assigns `v` to the last element of the container.) 350 ) 351 $(TR 352 $(TDNW `c[x]`) 353 $(TDNW $(D log n$(SUBSCRIPT c))) 354 $(TD Provides indexed access into the container. The index type is 355 container-defined. A container may define several index types (and 356 consequently overloaded indexing).) 357 ) 358 $(TR 359 $(TDNW `c.moveAt(x)`) 360 $(TDNW $(D log n$(SUBSCRIPT c))) 361 $(TD Destructively reads and returns the value at position `x`. The slot 362 is not removed from the container; it is left initialized with $(D 363 T.init).) 364 ) 365 $(TR 366 $(TDNW $(D c[x] = v)) 367 $(TDNW $(D log n$(SUBSCRIPT c))) 368 $(TD Sets element at specified index into the container.) 369 ) 370 $(TR 371 $(TDNW $(D c[x] $(I op)= v)) 372 $(TDNW $(D log n$(SUBSCRIPT c))) 373 $(TD Performs read-modify-write operation at specified index into the 374 container.) 375 ) 376 $(LEADINGROWN 3, Operations 377 ) 378 $(TR 379 $(TDNW $(D e in c)) 380 $(TDNW $(D log n$(SUBSCRIPT c))) 381 $(TD Returns nonzero if e is found in `c`.) 382 ) 383 $(TR 384 $(TDNW `c.lowerBound(v)`) 385 $(TDNW $(D log n$(SUBSCRIPT c))) 386 $(TD Returns a range of all elements strictly less than `v`.) 387 ) 388 $(TR 389 $(TDNW `c.upperBound(v)`) 390 $(TDNW $(D log n$(SUBSCRIPT c))) 391 $(TD Returns a range of all elements strictly greater than `v`.) 392 ) 393 $(TR 394 $(TDNW `c.equalRange(v)`) 395 $(TDNW $(D log n$(SUBSCRIPT c))) 396 $(TD Returns a range of all elements in `c` that are equal to `v`.) 397 ) 398 $(LEADINGROWN 3, Modifiers 399 ) 400 $(TR 401 $(TDNW $(D c ~= x)) 402 $(TDNW $(D n$(SUBSCRIPT c) + n$(SUBSCRIPT x))) 403 $(TD Appends `x` to `c`. `x` may be a single element or an input range type.) 404 ) 405 $(TR 406 $(TDNW `c.clear()`) 407 $(TDNW $(D n$(SUBSCRIPT c))) 408 $(TD Removes all elements in `c`.) 409 ) 410 $(TR 411 $(TDNW `c.insert(x)`) 412 $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c))) 413 $(TD Inserts `x` in `c` at a position (or positions) chosen by `c`.) 414 ) 415 $(TR 416 $(TDNW `c.stableInsert(x)`) 417 $(TDNW $(D n$(SUBSCRIPT x) * log n$(SUBSCRIPT c))) 418 $(TD Same as `c.insert(x)`, but is guaranteed to not invalidate any ranges.) 419 ) 420 $(TR 421 $(TDNW `c.linearInsert(v)`) 422 $(TDNW $(D n$(SUBSCRIPT c))) 423 $(TD Same as `c.insert(v)` but relaxes complexity to linear.) 424 ) 425 $(TR 426 $(TDNW `c.stableLinearInsert(v)`) 427 $(TDNW $(D n$(SUBSCRIPT c))) 428 $(TD Same as `c.stableInsert(v)` but relaxes complexity to linear.) 429 ) 430 $(TR 431 $(TDNW `c.removeAny()`) 432 $(TDNW $(D log n$(SUBSCRIPT c))) 433 $(TD Removes some element from `c` and returns it.) 434 ) 435 $(TR 436 $(TDNW `c.stableRemoveAny()`) 437 $(TDNW $(D log n$(SUBSCRIPT c))) 438 $(TD Same as `c.removeAny()`, but is guaranteed to not invalidate any 439 iterators.) 440 ) 441 $(TR 442 $(TDNW `c.insertFront(v)`) 443 $(TDNW $(D log n$(SUBSCRIPT c))) 444 $(TD Inserts `v` at the front of `c`.) 445 ) 446 $(TR 447 $(TDNW `c.stableInsertFront(v)`) 448 $(TDNW $(D log n$(SUBSCRIPT c))) 449 $(TD Same as `c.insertFront(v)`, but guarantees no ranges will be 450 invalidated.) 451 ) 452 $(TR 453 $(TDNW `c.insertBack(v)`) 454 $(TDNW $(D log n$(SUBSCRIPT c))) 455 $(TD Inserts `v` at the back of `c`.) 456 ) 457 $(TR 458 $(TDNW `c.stableInsertBack(v)`) 459 $(TDNW $(D log n$(SUBSCRIPT c))) 460 $(TD Same as `c.insertBack(v)`, but guarantees no ranges will be 461 invalidated.) 462 ) 463 $(TR 464 $(TDNW `c.removeFront()`) 465 $(TDNW $(D log n$(SUBSCRIPT c))) 466 $(TD Removes the element at the front of `c`.) 467 ) 468 $(TR 469 $(TDNW `c.stableRemoveFront()`) 470 $(TDNW $(D log n$(SUBSCRIPT c))) 471 $(TD Same as `c.removeFront()`, but guarantees no ranges will be 472 invalidated.) 473 ) 474 $(TR 475 $(TDNW `c.removeBack()`) 476 $(TDNW $(D log n$(SUBSCRIPT c))) 477 $(TD Removes the value at the back of `c`.) 478 ) 479 $(TR 480 $(TDNW `c.stableRemoveBack()`) 481 $(TDNW $(D log n$(SUBSCRIPT c))) 482 $(TD Same as `c.removeBack()`, but guarantees no ranges will be 483 invalidated.) 484 ) 485 $(TR 486 $(TDNW `c.remove(r)`) 487 $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c))) 488 $(TD Removes range `r` from `c`.) 489 ) 490 $(TR 491 $(TDNW `c.stableRemove(r)`) 492 $(TDNW $(D n$(SUBSCRIPT r) * log n$(SUBSCRIPT c))) 493 $(TD Same as `c.remove(r)`, but guarantees iterators are not 494 invalidated.) 495 ) 496 $(TR 497 $(TDNW `c.linearRemove(r)`) 498 $(TDNW $(D n$(SUBSCRIPT c))) 499 $(TD Removes range `r` from `c`.) 500 ) 501 $(TR 502 $(TDNW `c.stableLinearRemove(r)`) 503 $(TDNW $(D n$(SUBSCRIPT c))) 504 $(TD Same as `c.linearRemove(r)`, but guarantees iterators are not 505 invalidated.) 506 ) 507 $(TR 508 $(TDNW `c.removeKey(k)`) 509 $(TDNW $(D log n$(SUBSCRIPT c))) 510 $(TD Removes an element from `c` by using its key `k`. 511 The key's type is defined by the container.) 512 ) 513 ) 514 515 Source: $(PHOBOSSRC std/container/package.d) 516 517 Copyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code 518 copyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders. 519 520 License: Distributed under the Boost Software License, Version 1.0. 521 (See accompanying file LICENSE_1_0.txt or copy at $(HTTP 522 boost.org/LICENSE_1_0.txt)). 523 524 Authors: Steven Schveighoffer, $(HTTP erdani.com, Andrei Alexandrescu) 525 */ 526 527 module std.container; 528 529 public import std.container.array; 530 public import std.container.binaryheap; 531 public import std.container.dlist; 532 public import std.container.rbtree; 533 public import std.container.slist; 534 535 import std.meta; 536 537 538 /* The following documentation and type `TotalContainer` are 539 intended for developers only. 540 541 `TotalContainer` is an unimplemented container that illustrates a 542 host of primitives that a container may define. It is to some extent 543 the bottom of the conceptual container hierarchy. A given container 544 most often will choose to only implement a subset of these primitives, 545 and define its own additional ones. Adhering to the standard primitive 546 names below allows generic code to work independently of containers. 547 548 Things to remember: any container must be a reference type, whether 549 implemented as a `class` or `struct`. No primitive below 550 requires the container to escape addresses of elements, which means 551 that compliant containers can be defined to use reference counting or 552 other deterministic memory management techniques. 553 554 A container may choose to define additional specific operations. The 555 only requirement is that those operations bear different names than 556 the ones below, lest user code gets confused. 557 558 Complexity of operations should be interpreted as "at least as good 559 as". If an operation is required to have $(BIGOH n) complexity, it 560 could have anything lower than that, e.g. $(BIGOH log(n)). Unless 561 specified otherwise, `n` inside a $(BIGOH) expression stands for 562 the number of elements in the container. 563 */ 564 struct TotalContainer(T) 565 { 566 /** 567 If the container has a notion of key-value mapping, `KeyType` 568 defines the type of the key of the container. 569 */ 570 alias KeyType = T; 571 572 /** 573 If the container has a notion of multikey-value mapping, $(D 574 KeyTypes[k]), where `k` is a zero-based unsigned number, defines 575 the type of the `k`th key of the container. 576 577 A container may define both `KeyType` and `KeyTypes`, e.g. in 578 the case it has the notion of primary/preferred key. 579 */ 580 alias KeyTypes = AliasSeq!T; 581 582 /** 583 If the container has a notion of key-value mapping, `ValueType` 584 defines the type of the value of the container. Typically, a map-style 585 container mapping values of type `K` to values of type `V` 586 defines `KeyType` to be `K` and `ValueType` to be `V`. 587 */ 588 alias ValueType = T; 589 590 /** 591 Defines the container's primary range, which embodies one of the 592 ranges defined in $(MREF std,range). 593 594 Generally a container may define several types of ranges. 595 */ 596 struct Range 597 { 598 /++ 599 Range primitives. 600 +/ 601 @property bool empty() 602 { 603 assert(0, "Not implemented"); 604 } 605 /// Ditto 606 @property ref T front() //ref return optional 607 { 608 assert(0, "Not implemented"); 609 } 610 /// Ditto 611 @property void front(T value) //Only when front does not return by ref 612 { 613 assert(0, "Not implemented"); 614 } 615 /// Ditto 616 T moveFront() 617 { 618 assert(0, "Not implemented"); 619 } 620 /// Ditto 621 void popFront() 622 { 623 assert(0, "Not implemented"); 624 } 625 /// Ditto 626 @property ref T back() //ref return optional 627 { 628 assert(0, "Not implemented"); 629 } 630 /// Ditto 631 @property void back(T value) //Only when front does not return by ref 632 { 633 assert(0, "Not implemented"); 634 } 635 /// Ditto 636 T moveBack() 637 { 638 assert(0, "Not implemented"); 639 } 640 /// Ditto 641 void popBack() 642 { 643 assert(0, "Not implemented"); 644 } 645 /// Ditto 646 T opIndex(size_t i) //ref return optional 647 { 648 assert(0, "Not implemented"); 649 } 650 /// Ditto 651 void opIndexAssign(size_t i, T value) //Only when front does not return by ref 652 { 653 assert(0, "Not implemented"); 654 } 655 /// Ditto 656 T opIndexUnary(string op)(size_t i) //Only when front does not return by ref 657 { 658 assert(0, "Not implemented"); 659 } 660 /// Ditto 661 void opIndexOpAssign(string op)(size_t i, T value) //Only when front does not return by ref 662 { 663 assert(0, "Not implemented"); 664 } 665 /// Ditto 666 T moveAt(size_t i) 667 { 668 assert(0, "Not implemented"); 669 } 670 /// Ditto 671 @property size_t length() 672 { 673 assert(0, "Not implemented"); 674 } 675 } 676 677 /** 678 Property returning `true` if and only if the container has no 679 elements. 680 681 Complexity: $(BIGOH 1) 682 */ 683 @property bool empty() 684 { 685 assert(0, "Not implemented"); 686 } 687 688 /** 689 Returns a duplicate of the container. The elements themselves are not 690 transitively duplicated. 691 692 Complexity: $(BIGOH n). 693 */ 694 @property TotalContainer dup() 695 { 696 assert(0, "Not implemented"); 697 } 698 699 /** 700 Returns the number of elements in the container. 701 702 Complexity: $(BIGOH log(n)). 703 */ 704 @property size_t length() 705 { 706 assert(0, "Not implemented"); 707 } 708 709 /** 710 Returns the maximum number of elements the container can store without 711 (a) allocating memory, (b) invalidating iterators upon insertion. 712 713 Complexity: $(BIGOH log(n)). 714 */ 715 @property size_t capacity() 716 { 717 assert(0, "Not implemented"); 718 } 719 720 /** 721 Ensures sufficient capacity to accommodate `n` elements. 722 723 Postcondition: $(D capacity >= n) 724 725 Complexity: $(BIGOH log(e - capacity)) if $(D e > capacity), otherwise 726 $(BIGOH 1). 727 */ 728 void reserve(size_t e) 729 { 730 assert(0, "Not implemented"); 731 } 732 733 /** 734 Returns a range that iterates over all elements of the container, in a 735 container-defined order. The container should choose the most 736 convenient and fast method of iteration for `opSlice()`. 737 738 Complexity: $(BIGOH log(n)) 739 */ 740 Range opSlice() 741 { 742 assert(0, "Not implemented"); 743 } 744 745 /** 746 Returns a range that iterates the container between two 747 specified positions. 748 749 Complexity: $(BIGOH log(n)) 750 */ 751 Range opSlice(size_t a, size_t b) 752 { 753 assert(0, "Not implemented"); 754 } 755 756 /** 757 Forward to `opSlice().front` and `opSlice().back`, respectively. 758 759 Complexity: $(BIGOH log(n)) 760 */ 761 @property ref T front() //ref return optional 762 { 763 assert(0, "Not implemented"); 764 } 765 /// Ditto 766 @property void front(T value) //Only when front does not return by ref 767 { 768 assert(0, "Not implemented"); 769 } 770 /// Ditto 771 T moveFront() 772 { 773 assert(0, "Not implemented"); 774 } 775 /// Ditto 776 @property ref T back() //ref return optional 777 { 778 assert(0, "Not implemented"); 779 } 780 /// Ditto 781 @property void back(T value) //Only when front does not return by ref 782 { 783 assert(0, "Not implemented"); 784 } 785 /// Ditto 786 T moveBack() 787 { 788 assert(0, "Not implemented"); 789 } 790 791 /** 792 Indexing operators yield or modify the value at a specified index. 793 */ 794 ref T opIndex(KeyType) //ref return optional 795 { 796 assert(0, "Not implemented"); 797 } 798 /// ditto 799 void opIndexAssign(KeyType i, T value) //Only when front does not return by ref 800 { 801 assert(0, "Not implemented"); 802 } 803 /// ditto 804 T opIndexUnary(string op)(KeyType i) //Only when front does not return by ref 805 { 806 assert(0, "Not implemented"); 807 } 808 /// ditto 809 void opIndexOpAssign(string op)(KeyType i, T value) //Only when front does not return by ref 810 { 811 assert(0, "Not implemented"); 812 } 813 /// ditto 814 T moveAt(KeyType i) 815 { 816 assert(0, "Not implemented"); 817 } 818 819 /** 820 $(D k in container) returns true if the given key is in the container. 821 */ 822 bool opBinaryRight(string op)(KeyType k) 823 if (op == "in") 824 { 825 assert(0, "Not implemented"); 826 } 827 828 /** 829 Returns a range of all elements containing `k` (could be empty or a 830 singleton range). 831 */ 832 Range equalRange(KeyType k) 833 { 834 assert(0, "Not implemented"); 835 } 836 837 /** 838 Returns a range of all elements with keys less than `k` (could be 839 empty or a singleton range). Only defined by containers that store 840 data sorted at all times. 841 */ 842 Range lowerBound(KeyType k) 843 { 844 assert(0, "Not implemented"); 845 } 846 847 /** 848 Returns a range of all elements with keys larger than `k` (could be 849 empty or a singleton range). Only defined by containers that store 850 data sorted at all times. 851 */ 852 Range upperBound(KeyType k) 853 { 854 assert(0, "Not implemented"); 855 } 856 857 /** 858 Returns a new container that's the concatenation of `this` and its 859 argument. `opBinaryRight` is only defined if `Stuff` does not 860 define `opBinary`. 861 862 Complexity: $(BIGOH n + m), where m is the number of elements in $(D 863 stuff) 864 */ 865 TotalContainer opBinary(string op)(Stuff rhs) 866 if (op == "~") 867 { 868 assert(0, "Not implemented"); 869 } 870 871 /// ditto 872 TotalContainer opBinaryRight(string op)(Stuff lhs) 873 if (op == "~") 874 { 875 assert(0, "Not implemented"); 876 } 877 878 /** 879 Forwards to $(D insertAfter(this[], stuff)). 880 */ 881 void opOpAssign(string op)(Stuff stuff) 882 if (op == "~") 883 { 884 assert(0, "Not implemented"); 885 } 886 887 /** 888 Removes all contents from the container. The container decides how $(D 889 capacity) is affected. 890 891 Postcondition: `empty` 892 893 Complexity: $(BIGOH n) 894 */ 895 void clear() 896 { 897 assert(0, "Not implemented"); 898 } 899 900 /** 901 Sets the number of elements in the container to `newSize`. If $(D 902 newSize) is greater than `length`, the added elements are added to 903 unspecified positions in the container and initialized with $(D 904 .init). 905 906 Complexity: $(BIGOH abs(n - newLength)) 907 908 Postcondition: $(D _length == newLength) 909 */ 910 @property void length(size_t newLength) 911 { 912 assert(0, "Not implemented"); 913 } 914 915 /** 916 Inserts `stuff` in an unspecified position in the 917 container. Implementations should choose whichever insertion means is 918 the most advantageous for the container, but document the exact 919 behavior. `stuff` can be a value convertible to the element type of 920 the container, or a range of values convertible to it. 921 922 The `stable` version guarantees that ranges iterating over the 923 container are never invalidated. Client code that counts on 924 non-invalidating insertion should use `stableInsert`. Such code would 925 not compile against containers that don't support it. 926 927 Returns: The number of elements added. 928 929 Complexity: $(BIGOH m * log(n)), where `m` is the number of 930 elements in `stuff` 931 */ 932 size_t insert(Stuff)(Stuff stuff) 933 { 934 assert(0, "Not implemented"); 935 } 936 ///ditto 937 size_t stableInsert(Stuff)(Stuff stuff) 938 { 939 assert(0, "Not implemented"); 940 } 941 942 /** 943 Same as `insert(stuff)` and `stableInsert(stuff)` respectively, 944 but relax the complexity constraint to linear. 945 */ 946 size_t linearInsert(Stuff)(Stuff stuff) 947 { 948 assert(0, "Not implemented"); 949 } 950 ///ditto 951 size_t stableLinearInsert(Stuff)(Stuff stuff) 952 { 953 assert(0, "Not implemented"); 954 } 955 956 /** 957 Picks one value in an unspecified position in the container, removes 958 it from the container, and returns it. Implementations should pick the 959 value that's the most advantageous for the container. The stable version 960 behaves the same, but guarantees that ranges iterating over the container 961 are never invalidated. 962 963 Precondition: `!empty` 964 965 Returns: The element removed. 966 967 Complexity: $(BIGOH log(n)). 968 */ 969 T removeAny() 970 { 971 assert(0, "Not implemented"); 972 } 973 /// ditto 974 T stableRemoveAny() 975 { 976 assert(0, "Not implemented"); 977 } 978 979 /** 980 Inserts `value` to the front or back of the container. `stuff` 981 can be a value convertible to the container's element type or a range 982 of values convertible to it. The stable version behaves the same, but 983 guarantees that ranges iterating over the container are never 984 invalidated. 985 986 Returns: The number of elements inserted 987 988 Complexity: $(BIGOH log(n)). 989 */ 990 size_t insertFront(Stuff)(Stuff stuff) 991 { 992 assert(0, "Not implemented"); 993 } 994 /// ditto 995 size_t stableInsertFront(Stuff)(Stuff stuff) 996 { 997 assert(0, "Not implemented"); 998 } 999 /// ditto 1000 size_t insertBack(Stuff)(Stuff stuff) 1001 { 1002 assert(0, "Not implemented"); 1003 } 1004 /// ditto 1005 size_t stableInsertBack(T value) 1006 { 1007 assert(0, "Not implemented"); 1008 } 1009 1010 /** 1011 Removes the value at the front or back of the container. The stable 1012 version behaves the same, but guarantees that ranges iterating over 1013 the container are never invalidated. The optional parameter $(D 1014 howMany) instructs removal of that many elements. If $(D howMany > n), 1015 all elements are removed and no exception is thrown. 1016 1017 Precondition: `!empty` 1018 1019 Complexity: $(BIGOH log(n)). 1020 */ 1021 void removeFront() 1022 { 1023 assert(0, "Not implemented"); 1024 } 1025 /// ditto 1026 void stableRemoveFront() 1027 { 1028 assert(0, "Not implemented"); 1029 } 1030 /// ditto 1031 void removeBack() 1032 { 1033 assert(0, "Not implemented"); 1034 } 1035 /// ditto 1036 void stableRemoveBack() 1037 { 1038 assert(0, "Not implemented"); 1039 } 1040 1041 /** 1042 Removes `howMany` values at the front or back of the 1043 container. Unlike the unparameterized versions above, these functions 1044 do not throw if they could not remove `howMany` elements. Instead, 1045 if $(D howMany > n), all elements are removed. The returned value is 1046 the effective number of elements removed. The stable version behaves 1047 the same, but guarantees that ranges iterating over the container are 1048 never invalidated. 1049 1050 Returns: The number of elements removed 1051 1052 Complexity: $(BIGOH howMany * log(n)). 1053 */ 1054 size_t removeFront(size_t howMany) 1055 { 1056 assert(0, "Not implemented"); 1057 } 1058 /// ditto 1059 size_t stableRemoveFront(size_t howMany) 1060 { 1061 assert(0, "Not implemented"); 1062 } 1063 /// ditto 1064 size_t removeBack(size_t howMany) 1065 { 1066 assert(0, "Not implemented"); 1067 } 1068 /// ditto 1069 size_t stableRemoveBack(size_t howMany) 1070 { 1071 assert(0, "Not implemented"); 1072 } 1073 1074 /** 1075 Removes all values corresponding to key `k`. 1076 1077 Complexity: $(BIGOH m * log(n)), where `m` is the number of 1078 elements with the same key. 1079 1080 Returns: The number of elements removed. 1081 */ 1082 size_t removeKey(KeyType k) 1083 { 1084 assert(0, "Not implemented"); 1085 } 1086 1087 /** 1088 Inserts `stuff` before, after, or instead range `r`, which must 1089 be a valid range previously extracted from this container. `stuff` 1090 can be a value convertible to the container's element type or a range 1091 of objects convertible to it. The stable version behaves the same, but 1092 guarantees that ranges iterating over the container are never 1093 invalidated. 1094 1095 Returns: The number of values inserted. 1096 1097 Complexity: $(BIGOH n + m), where `m` is the length of `stuff` 1098 */ 1099 size_t insertBefore(Stuff)(Range r, Stuff stuff) 1100 { 1101 assert(0, "Not implemented"); 1102 } 1103 /// ditto 1104 size_t stableInsertBefore(Stuff)(Range r, Stuff stuff) 1105 { 1106 assert(0, "Not implemented"); 1107 } 1108 /// ditto 1109 size_t insertAfter(Stuff)(Range r, Stuff stuff) 1110 { 1111 assert(0, "Not implemented"); 1112 } 1113 /// ditto 1114 size_t stableInsertAfter(Stuff)(Range r, Stuff stuff) 1115 { 1116 assert(0, "Not implemented"); 1117 } 1118 /// ditto 1119 size_t replace(Stuff)(Range r, Stuff stuff) 1120 { 1121 assert(0, "Not implemented"); 1122 } 1123 /// ditto 1124 size_t stableReplace(Stuff)(Range r, Stuff stuff) 1125 { 1126 assert(0, "Not implemented"); 1127 } 1128 1129 /** 1130 Removes all elements belonging to `r`, which must be a range 1131 obtained originally from this container. The stable version behaves the 1132 same, but guarantees that ranges iterating over the container are 1133 never invalidated. 1134 1135 Returns: A range spanning the remaining elements in the container that 1136 initially were right after `r`. 1137 1138 Complexity: $(BIGOH m * log(n)), where `m` is the number of 1139 elements in `r` 1140 */ 1141 Range remove(Range r) 1142 { 1143 assert(0, "Not implemented"); 1144 } 1145 /// ditto 1146 Range stableRemove(Range r) 1147 { 1148 assert(0, "Not implemented"); 1149 } 1150 1151 /** 1152 Same as `remove` above, but has complexity relaxed to linear. 1153 1154 Returns: A range spanning the remaining elements in the container that 1155 initially were right after `r`. 1156 1157 Complexity: $(BIGOH n) 1158 */ 1159 Range linearRemove(Range r) 1160 { 1161 assert(0, "Not implemented"); 1162 } 1163 /// ditto 1164 Range stableLinearRemove(Range r) 1165 { 1166 assert(0, "Not implemented"); 1167 } 1168 } 1169 1170 @safe unittest 1171 { 1172 TotalContainer!int test; 1173 }