Skip to content

Commit 5649e71

Browse files
committed
Merge pull request #1 from davidmorgan/master
Add BuiltList, BuiltSet, BuiltMap, helper classes and tests.
2 parents 1428274 + 7324d74 commit 5649e71

20 files changed

+3592
-9
lines changed

lib/built_collection.dart

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
part of built_collection;
6+
7+
/// Internal only test helpers.
8+
class BuiltCollectionTestHelpers {
9+
static BuiltMap<int, String> overridenHashcodeBuiltMap(map, int hashCode) =>
10+
new _OverriddenHashcodeBuiltMap<int, String>(map, hashCode);
11+
12+
static BuiltList<int> overridenHashcodeBuiltList(
13+
Iterable iterable, int hashCode) =>
14+
new _OverriddenHashcodeBuiltList<int>(iterable, hashCode);
15+
16+
static BuiltSet<int> overridenHashcodeBuiltSet(
17+
Iterable iterable, int hashCode) =>
18+
new _OverriddenHashcodeBuiltSet<int>(iterable, hashCode);
19+
}
20+
21+
class _OverriddenHashcodeBuiltMap<K, V> extends BuiltMap<K, V> {
22+
final int _hashCode;
23+
24+
_OverriddenHashcodeBuiltMap(map, this._hashCode)
25+
: super._copyAndCheck(map.keys, (k) => map[k]);
26+
27+
int get hashCode => _hashCode;
28+
}
29+
30+
class _OverriddenHashcodeBuiltList<T> extends BuiltList<T> {
31+
final int _hashCode;
32+
33+
_OverriddenHashcodeBuiltList(Iterable iterable, this._hashCode)
34+
: super._copyAndCheck(iterable);
35+
36+
int get hashCode => _hashCode;
37+
}
38+
39+
class _OverriddenHashcodeBuiltSet<T> extends BuiltSet<T> {
40+
final int _hashCode;
41+
42+
_OverriddenHashcodeBuiltSet(Iterable iterable, this._hashCode)
43+
: super._copyAndCheck(iterable);
44+
45+
int get hashCode => _hashCode;
46+
}

0 commit comments

Comments
 (0)