Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add remaining .empty() const factories #74

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ IList<String> ilist = [1, 2].lock;

// Locking a set as list
IList<String> ilist = {1, 2}.toIList();

// Creating an empty IList
IList<String> ilist = const IList.empty();
```

To create a regular `List` from an `IList`, you can use `List.of`, or simply "unlock" an immutable
Expand Down Expand Up @@ -900,6 +903,9 @@ ISet<String> iset = {1, 2}.lock;

// Locking a list as set
ISet<String> iset = [1, 2].toISet();

// Creating an empty ISet
ISet<String> iset = const ISet.empty();
```

To create a regular `Set` from an `ISet`, you can use `Set.of`, or simply "unlock" an immutable set:
Expand Down Expand Up @@ -1070,6 +1076,9 @@ IMap<String, int> imap = {"a": 1, "b": 2}.lock;
// From map entries
IMap<String, int> imap = IMap.fromEntries([MapEntry("a", 1), MapEntry("b", 2)]);

// Creating an empty IMap
IMap<String> imap = const IMap.empty();

// From keys and a value-mapper
// This results in {"Jim": 3, "David": 5}
IMap<String, int> imap =
Expand Down
43 changes: 43 additions & 0 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ void main() {
final bool containsThirty = iList.contains(30);
print('Does the list contain 30? $containsThirty');

// Creating a empty IList
const emptyIList = IList<String>.empty();
print("Empty IList is empty? ${emptyIList.isEmpty}");



// Example usage of ISet.
print('\nISet Example:');
ISet<String> iSet = ISet<String>();
Expand All @@ -42,4 +48,41 @@ void main() {
for (final String fruit in iSet) {
print(fruit);
}

// Creating a empty ISet
const emptyISet = ISet<String>.empty();
print("Empty ISet is empty? ${emptyISet.isEmpty}");



// Example usage of IMap
print('\nIMap Example:');
IMap<String, String> iMap = IMap<String, String>();

// Add elements to the map.
iMap = iMap.add('apple', 'red');
iMap = iMap.addEntries([
const MapEntry('banana', 'yellow'),
const MapEntry('orange', 'orange'),
const MapEntry('grape', 'green')
]);
print('Original Map: $iMap');

// Remove an element from the map.
iMap = iMap.remove('orange');
print('Map after removing orange: $iMap');

// Check if the map contains an element.
final bool containsApple = iMap.containsKey('apple');
print('Does the map contain apple as a key? $containsApple');

// Iterate over the elements in the map.
print('Iterating over the map:');
for (final MapEntry<String, String> fruitAndColor in iMap.entries) {
print("${fruitAndColor.key}: ${fruitAndColor.value}");
}

// Creating a empty IMap
const emptyIMap = IMap<String, String>.empty();
print("Empty IMap is empty? ${emptyIMap.isEmpty}");
}
8 changes: 4 additions & 4 deletions lib/src/ilist/ilist.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,17 @@ class IListConst<T> // ignore: must_be_immutable
[this.config = const ConfigList()])
: super._gen();

final List<T> _list;

/// Creates a empty constant list.
///
/// IMPORTANT: You must always use the `const` keyword.
/// It's always wrong to use an `IListConst.empty()` which is not constant.
@literal
const IListConst.empty([this.config = const ConfigList()])
: _list = const [],
super._gen();

final List<T> _list;

@override
final ConfigList config;

Expand Down Expand Up @@ -198,9 +199,8 @@ abstract class IList<T> // ignore: must_be_immutable
factory IList([Iterable<T>? iterable]) => //
IList.withConfig(iterable ?? const [], defaultConfig);


/// Create an empty [IList].
/// It is always a constant list.
/// It is always a [IListConst].
const factory IList.empty() = IListConst<T>.empty;

const IList._gen();
Expand Down
14 changes: 14 additions & 0 deletions lib/src/imap/imap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ class IMapConst<K, V> // ignore: must_be_immutable
[this.config = const ConfigMap()])
: super._gen();


/// Creates a empty constant map.
///
/// IMPORTANT: You must always use the `const` keyword.
/// It's always wrong to use an `IMapConst.empty()` which is not constant.
@literal
const IMapConst.empty([this.config = const ConfigMap()])
: _map = const {},
super._gen();

final Map<K, V> _map;

@override
Expand Down Expand Up @@ -172,6 +182,10 @@ abstract class IMap<K, V> // ignore: must_be_immutable
factory IMap([Map<K, V>? map]) => //
IMap.withConfig(map, defaultConfig);

/// Create an empty [IMap].
/// It is always a [IMapConst].
const factory IMap.empty() = IMapConst<K, V>.empty;

const IMap._gen();

/// Create an [IMap] from a [Map] and a [ConfigMap].
Expand Down
13 changes: 13 additions & 0 deletions lib/src/iset/iset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ class ISetConst<T> // ignore: must_be_immutable
// because when you do this _set will be Set<Never> which is bad.
[this.config = const ConfigSet()])
: super._gen();

/// Creates a empty constant set.
///
/// IMPORTANT: You must always use the `const` keyword.
/// It's always wrong to use an `ISetConst.empty()` which is not constant.
@literal
const ISetConst.empty([this.config = const ConfigSet()])
: _set = const {},
super._gen();

final Set<T> _set;

Expand Down Expand Up @@ -187,6 +196,10 @@ abstract class ISet<T> // ignore: must_be_immutable
factory ISet([Iterable<T>? iterable]) => //
ISet.withConfig(iterable, defaultConfig);

/// Create an empty [ISet].
/// It is always a [ISetConst].
const factory ISet.empty() = ISetConst<T>.empty;

const ISet._gen();

/// Create an [ISet] from any [Iterable] and a [ConfigSet].
Expand Down
12 changes: 2 additions & 10 deletions test/ilist/ilist_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ void main() {
expect(IList([1]), isA<IList<int>>());
expect(IList<int>(), isA<IList<int>>());
expect([].lock, isA<IList>());
expect(IList.empty(), isA<IList>());
expect(IList<int>.empty(), isA<IList<int>>());
expect(const IList.empty(), isA<IList>());
expect(const IList<int>.empty(), isA<IList<int>>());
const IList untypedList = IList.empty();
expect(untypedList, isA<IList>());
const IList<int> intList = IList.empty();
expect(intList, isA<IList<int>>());
const IList<int> typedList = IList.empty();
expect(typedList, isA<IList<int>>());
});

test("isEmpty | isNotEmpty", () {
Expand All @@ -51,15 +49,9 @@ void main() {
expect([].lock.isEmpty, isTrue);
expect([].lock.isNotEmpty, isFalse);

expect(IList.empty().isEmpty, isTrue);
expect(IList.empty().isNotEmpty, isFalse);

expect(const IList.empty().isEmpty, isTrue);
expect(const IList.empty().isNotEmpty, isFalse);

expect(IList<String>.empty().isEmpty, isTrue);
expect(IList<String>.empty().isNotEmpty, isFalse);

expect(const IList<String>.empty().isEmpty, isTrue);
expect(const IList<String>.empty().isNotEmpty, isFalse);
});
Expand Down
10 changes: 10 additions & 0 deletions test/imap/imap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ void main() {
expect(IMap<String, int>({}), isA<IMap<String, int>>());
expect(IMap({"a": 1}), isA<IMap<String, int>>());
expect(IMapImpl.empty<String, int>(), isA<IMap<String, int>>());
expect(const IMap.empty(), isA<IMap>());
expect(const IMap<String, int>.empty(), isA<IMap<String, int>>());
const IMap untypedMap = IMap.empty();
expect(untypedMap, isA<IMap>());
const IMap<String, int> typedMap = IMap.empty();
expect(typedMap, isA<IMap<String, int>>());
});

test("isEmpty | isNotEmpty", () {
Expand All @@ -30,12 +36,16 @@ void main() {
expect(IMap<String, int>({}).isEmpty, isTrue);
expect(IMap({"a": 1}).isEmpty, isFalse);
expect(IMapImpl.empty<String, int>().isEmpty, isTrue);
expect(const IMap.empty().isEmpty, isTrue);
expect(const IMap<String, int>.empty().isEmpty, isTrue);

expect(IMap().isNotEmpty, isFalse);
expect(IMap({}).isNotEmpty, isFalse);
expect(IMap<String, int>({}).isNotEmpty, isFalse);
expect(IMap({"a": 1}).isNotEmpty, isTrue);
expect(IMapImpl.empty<String, int>().isNotEmpty, isFalse);
expect(const IMap.empty().isNotEmpty, isFalse);
expect(const IMap<String, int>.empty().isNotEmpty, isFalse);
});

test("unlock", () {
Expand Down
10 changes: 10 additions & 0 deletions test/iset/iset_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ void main() {
expect(ISet([1]), isA<ISet<int>>());
expect(ISet<int>(), isA<ISet<int>>());
expect(<int>{}.lock, isA<ISet>());
expect(const ISet.empty(), isA<ISet>());
expect(const ISet<int>.empty(), isA<ISet<int>>());
const ISet untypedList = ISet.empty();
expect(untypedList, isA<ISet>());
const ISet<int> typedList = ISet.empty();
expect(typedList, isA<ISet<int>>());
});

test("fromIterable", () {
Expand Down Expand Up @@ -62,13 +68,17 @@ void main() {
expect(ISet([1]).isEmpty, isFalse);
expect(ISet<int>().isEmpty, isTrue);
expect(<int>{}.lock.isEmpty, isTrue);
expect(const ISet.empty().isEmpty, isTrue);
expect(const ISet<String>.empty().isEmpty, isTrue);

expect(ISet().isNotEmpty, isFalse);
expect(ISet({}).isNotEmpty, isFalse);
expect(ISet<String>({}).isNotEmpty, isFalse);
expect(ISet([1]).isNotEmpty, isTrue);
expect(ISet<int>().isNotEmpty, isFalse);
expect(<int>{}.lock.isNotEmpty, isFalse);
expect(const ISet.empty().isNotEmpty, isFalse);
expect(const ISet<String>.empty().isNotEmpty, isFalse);
});

test("Ensuring Immutability", () {
Expand Down
Loading