|
| 1 | +// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details. |
| 2 | +// All rights reserved. Use of this source code is governed by a BSD-style |
| 3 | +// license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +/// Built Collections bring the benefits of immutability to your Dart code via |
| 6 | +/// the [builder pattern](http://en.wikipedia.org/wiki/Builder_pattern). |
| 7 | +/// |
| 8 | +/// Each of the core SDK collections is split in two: a mutable builder class |
| 9 | +/// and an immutable "built" class. Builders are for computation, |
| 10 | +/// "built" classes are for safely sharing with no need to copy defensively. |
| 11 | +/// |
| 12 | +/// Built collections: |
| 13 | +/// |
| 14 | +/// * are immutable, if the elements/keys/values used are immutable; |
| 15 | +/// * are comparable; |
| 16 | +/// * are hashable; |
| 17 | +/// * reject nulls; |
| 18 | +/// * require generic type parameters; |
| 19 | +/// * reject wrong-type elements; |
| 20 | +/// * use copy-on-write to avoid copying unnecessarily. |
| 21 | +/// |
| 22 | +/// See below for details on each of these points. |
| 23 | +/// |
| 24 | +/// |
| 25 | +/// # Recommend Style |
| 26 | +/// |
| 27 | +/// A project can benefit greatly from using Built Collections throughout. |
| 28 | +/// Methods that will not mutate a collection can accept the "built" version, |
| 29 | +/// making it clear that no mutation will happen and completely avoiding |
| 30 | +/// the need for defensive copying. |
| 31 | +/// |
| 32 | +/// For code that is public to other projects or teams not using |
| 33 | +/// Built Collections, prefer to accept `Iterable` where possible. That way |
| 34 | +/// your code is compatible with SDK collections, Built Collections and any |
| 35 | +/// other collection implementation that builds on `Iterable`. |
| 36 | +/// |
| 37 | +/// It's okay to accept `List`, `Set` or `Map` if needed. Built Collections |
| 38 | +/// provide efficient conversion to their SDK counterparts via |
| 39 | +/// [BuiltList.toList], [BuiltSet.toSet] and [BuiltMap.toMap]. |
| 40 | +/// |
| 41 | +/// |
| 42 | +/// # Built Collections are Immutable |
| 43 | +/// |
| 44 | +/// Built Collections do not offer any methods that modify the collection. In |
| 45 | +/// order to make changes, first call `toBuilder` to get a mutable builder. |
| 46 | +/// |
| 47 | +/// In particular, Built Collections do not implement or extend their mutable |
| 48 | +/// counterparts. [BuiltList] implements `Iterable`, but not `List`. [BuiltSet] |
| 49 | +/// implements `Iterable`, but not `Set`. And [BuiltMap] shares no interface |
| 50 | +/// with the SDK collections. |
| 51 | +/// |
| 52 | +/// Built Collections can contain mutable elements. However, this use is not |
| 53 | +/// recommended, as mutations to the elements will break comparison and |
| 54 | +/// hashing. |
| 55 | +/// |
| 56 | +/// |
| 57 | +/// # Built Collections are Comparable |
| 58 | +/// |
| 59 | +/// Core SDK collections do not offer equality checks by default. |
| 60 | +/// |
| 61 | +/// Built Collections do a deep comparison against other Built Collections |
| 62 | +/// of the same type, only. Hashing is used to make repeated comparisons fast. |
| 63 | +/// |
| 64 | +/// |
| 65 | +/// # Built Collections are Hashable |
| 66 | +/// |
| 67 | +/// Core SDK collections do not compute a deep hashCode. |
| 68 | +/// |
| 69 | +/// Built Collections do compute, and cache, a deep hashCode. That means they |
| 70 | +/// can be stored inside collections that need hashing, such as hash sets and |
| 71 | +/// hash maps. They also use the cached hash code to speed up repeated |
| 72 | +/// comparisons. |
| 73 | +/// |
| 74 | +/// |
| 75 | +/// # Built Collections Reject Nulls |
| 76 | +/// |
| 77 | +/// A `null` in a collection is usually a bug, so Built Collections and their |
| 78 | +/// builders throw if given a `null` element, key or value. |
| 79 | +/// |
| 80 | +/// |
| 81 | +/// # Built Collections Require Generic Type Parameters |
| 82 | +/// |
| 83 | +/// A `List<dynamic>` is error-prone because it can be assigned to a `List` of |
| 84 | +/// any type without warning. So, all Built Collections must be created with |
| 85 | +/// explicit element, key or value types. |
| 86 | +/// |
| 87 | +/// |
| 88 | +/// # Built Collections Reject Wrong-type Elements, Keys and Values |
| 89 | +/// |
| 90 | +/// Collections that happen to contain elements, keys or values that are not of |
| 91 | +/// the right type can lead to difficult-to-find bugs. So, all Built |
| 92 | +/// Collections and their builders are aggressive about validating types, even |
| 93 | +/// with checked mode disabled. |
| 94 | +/// |
| 95 | +/// |
| 96 | +/// # Built Collections Avoid Copying Unnecessarily |
| 97 | +/// |
| 98 | +/// Built Collections and their builder and helper types collaborate to avoid |
| 99 | +/// copying unless it's necessary. |
| 100 | +/// |
| 101 | +/// In particular, [BuiltList.toList], [BuiltSet.toSet] and [BuiltMap.toMap] |
| 102 | +/// do not make a copy, but return a copy-on-write wrapper. So, Built |
| 103 | +/// Collections can be efficiently and easily used with code that needs core |
| 104 | +/// SDK collections but does not mutate them. |
| 105 | +library built_collection; |
| 106 | + |
| 107 | +import 'dart:math' show Random; |
| 108 | + |
| 109 | +import 'package:quiver/core.dart' show hashObjects, hash2; |
| 110 | + |
| 111 | +part 'src/list/built_list.dart'; |
| 112 | +part 'src/list/list_builder.dart'; |
| 113 | + |
| 114 | +part 'src/map/built_map.dart'; |
| 115 | +part 'src/map/map_builder.dart'; |
| 116 | + |
| 117 | +part 'src/set/built_set.dart'; |
| 118 | +part 'src/set/set_builder.dart'; |
| 119 | + |
| 120 | +part 'src/internal/copy_on_write_list.dart'; |
| 121 | +part 'src/internal/copy_on_write_map.dart'; |
| 122 | +part 'src/internal/copy_on_write_set.dart'; |
| 123 | +part 'src/internal/built_collection_test_helpers.dart'; |
| 124 | +part 'src/internal/unused_class.dart'; |
0 commit comments