Skip to content

Commit

Permalink
Add nullable numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
Pante committed Jun 11, 2024
1 parent 4c0ebb7 commit 3bf7d55
Show file tree
Hide file tree
Showing 5 changed files with 618 additions and 5 deletions.
11 changes: 6 additions & 5 deletions nitrogen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ Widget build(BuildContext context) => Assets.images.foo();

## Getting started

3rd party packages are supported via 'extension' packages:
3rd party packages are supported via 'extension' packages. `extension` packages generate `extension`s in separate files.
These `extension`s provide a `call(...)` function that transforms an `Asset` into a 3rd party type.

| Type | Package | Extension Package | Version |
|-------------------|---------------|------------------------|----------------------------------------------------------------------------------------------------------------|
| SVG images | `flutter_svg` | `nitrogen_flutter_svg` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_flutter_svg)](https://pub.dev/packages/nitrogen_flutter_svg) |
| Lottie animations | `lottie` | `nitrogen_lottie` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_lottie)](https://pub.dev/packages/nitrogen_lottie) |
| Type | Package | Extension Package | Version | Default generated file |
|-------------------|---------------|------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------|
| SVG images | `flutter_svg` | `nitrogen_flutter_svg` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_flutter_svg)](https://pub.dev/packages/nitrogen_flutter_svg) | `svg_extension.nitrogen.dart` |
| Lottie animations | `lottie` | `nitrogen_lottie` | [![Pub Dev](https://img.shields.io/pub/v/nitrogen_lottie)](https://pub.dev/packages/nitrogen_lottie) | `lottie_extension.nitrogen.dart` |


Install the following:
Expand Down
3 changes: 3 additions & 0 deletions sugar/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
- Add `Sil`

## `sugar.math`
- Add `NullableNumbers`
- Add `NullableIntegers`
- Add `NullableDoubles`
- **Breaking** Change `double.approximately(...)` to `double.around(...)`

## `sugar.time`
Expand Down
1 change: 1 addition & 0 deletions sugar/lib/math.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ import 'package:sugar/src/math/numbers.dart';
import 'package:sugar/src/math/random.dart';

export 'src/math/arithmetic_exception.dart';
export 'src/math/nullable.dart';
export 'src/math/numbers.dart';
export 'src/math/random.dart';
353 changes: 353 additions & 0 deletions sugar/lib/src/math/nullable.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,353 @@
/// Provides functions for working with nullable [num]s, specifically their operator overloads which do not work with
/// the null-aware operator.
///
/// ## Note:
/// Chaining functions provided by this extension is not recommended in performance sensitive contexts due to the
/// repeated null checks with each function call.
extension NullableNumbers on num? {

/// Returns the sum of this and [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a + b;
///
/// foo(1, null); // null
/// foo(1, 2); // 3
/// ```
num? operator +(num? other) => (this == null || other == null) ? null : this! + other;

/// Returns the difference of this and [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a - b;
///
/// foo(1, null); // null
/// foo(1, 2); // -1
/// ```
num? operator -(num? other) => (this == null || other == null) ? null : this! - other;

/// Returns the product of this and [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a * b;
///
/// foo(1, null); // null
/// foo(1, 2); // 2
/// ```
num? operator *(num? other) => (this == null || other == null) ? null : this! * other;

/// Returns the remainder of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a % b;
///
/// foo(1, null); // null
/// foo(1, 2); // 1
/// ```
num? operator %(num? other) => (this == null || other == null) ? null : this! % other;

/// Returns the quotient of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a / b;
///
/// foo(1, null); // null
/// foo(1, 2); // 0.5
/// ```
num? operator /(num? other) => (this == null || other == null) ? null : this! / other;

/// Returns the integer quotient of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a ~/ b;
///
/// foo(1, null); // null
/// foo(1, 2); // 0
/// ```
int? operator ~/(num? other) => (this == null || other == null) ? null : this! ~/ other;

/// Returns the negation of this, or `null` if this is `null`.
///
/// ```dart
/// num? foo(num? a) => -a;
///
/// foo(null); // null
/// foo(1); // -1
/// ```
num? operator -() => this == null ? null : -this!;


/// Returns whether this is less than [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a < b;
///
/// foo(1, null); // null
/// foo(1, 2); // true
/// ```
bool? operator <(num? other) => (this == null || other == null) ? null : this! < other;

/// Returns whether this is less than or equal than [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a <= b;
///
/// foo(1, null); // null
/// foo(1, 1); // true
/// ```
bool? operator <=(num? other) => (this == null || other == null) ? null : this! <= other;

/// Returns whether this is greater than [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a > b;
///
/// foo(1, null); // null
/// foo(1, 2); // false
/// ```
bool? operator >(num? other) =>( this == null || other == null) ? null : this! > other;

/// Returns whether this is greater than or equal to [other], or `null` if either is `null`.
///
/// ```dart
/// num? foo(num? a, num? b) => a >= b;
///
/// foo(1, null); // null
/// foo(1, 2); // true
/// ```
bool? operator >=(num? other) =>( this == null || other == null) ? null : this! >= other;

}

/// Provides functions for working with nullable [int]s, specifically their operator overloads which do not work with
/// the null-aware operator.
///
/// ## Note:
/// Chaining functions provided by this extension is not recommended in performance sensitive contexts due to the
/// repeated null checks with each function call.
extension NullableIntegers on int? {

/// Returns the bitwise AND of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a & b;
///
/// foo(1, null); // null
/// foo(1, 2); // 0
/// ```
int? operator &(int? other) => (this == null || other == null) ? null : this! & other;

/// Returns the bitwise OR of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a | b;
///
/// foo(1, null); // null
/// foo(1, 2); // 3
/// ```
int? operator |(int? other) => (this == null || other == null) ? null : this! | other;

/// Returns the bitwise XOR of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a ^ b;
///
/// foo(1, null); // null
/// foo(3, 5); // 6
/// ```
int? operator ^(int? other) => (this == null || other == null) ? null : this! ^ other;

/// Returns the bitwise NOT of this, or `null` if this is `null`.
///
/// ```dart
/// int? foo(int? a) => ~a;
///
/// foo(null); // null
/// foo(1); // -2
/// ```
int? operator ~() => this == null ? null : ~this!;

/// Shifts the bits of this integer to the left by [shiftAmount], or returns `null` if either is `null`.
///
/// Shifting to the left makes the number larger, effectively multiplying the number by `pow(2, shiftAmount)`.
///
/// There is no limit on the size of the result. It may be relevant to limit intermediate values by using the "and"
/// operator with a suitable mask.
///
/// ## Contract:
/// Throws an error if [shiftAmount] is negative.
///
/// ## Example:
/// ```dart
/// print((3 << 1).toRadixString(2)); // 0011 -> 0110
/// print((9 << 2).toRadixString(2)); // 1001 -> 100100
/// print((10 << 3).toRadixString(2)); // 1010 -> 1010000
/// ```
int? operator <<(int? shiftAmount) => (this == null || shiftAmount == null) ? null : this! << shiftAmount;

/// Shifts the bits of this integer to the right by [shiftAmount], or returns `null` if either is `null`.
///
/// Shifting to the right makes the number smaller and drops the least significant bits, effectively doing an integer
/// division by `pow(2, shiftAmount)`.
///
/// ## Contract:
/// Throws an error if [shiftAmount] is negative.
///
/// ## Example:
/// ```dart
/// print((3 >> 1).toRadixString(2)); // 0011 -> 0001
/// print((9 >> 2).toRadixString(2)); // 1001 -> 0010
/// print((10 >> 3).toRadixString(2)); // 1010 -> 0001
/// print((-6 >> 2).toRadixString); // 111...1010 -> 111...1110 == -2
/// print((-85 >> 3).toRadixString); // 111...10101011 -> 111...11110101 == -11
/// ```
int? operator >>(int? shiftAmount) => (this == null || shiftAmount == null) ? null : this! >> shiftAmount;

/// Bitwise unsigned right shift by [shiftAmount] bits.
///
/// The least significant [shiftAmount] bits are dropped, the remaining bits (if any) are shifted down, and zero-bits
/// are shifted in as the new most significant bits.
///
/// ## Contract:
/// Throws an error if [shiftAmount] is negative.
///
/// ## Example:
/// ```dart
/// print((3 >>> 1).toRadixString(2)); // 0011 -> 0001
/// print((9 >>> 2).toRadixString(2)); // 1001 -> 0010
/// print(((-9) >>> 2).toRadixString(2)); // 111...1011 -> 001...1110 (> 0)
/// ```
int? operator >>>(int? shiftAmount) => (this == null || shiftAmount == null) ? null : this! >> shiftAmount;


/// Returns the sum of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a + b;
///
/// foo(1, null); // null
/// foo(1, 2); // 3
/// ```
int? operator +(int? other) => (this == null || other == null) ? null : this! + other;

/// Returns the difference of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a - b;
///
/// foo(1, null); // null
/// foo(1, 2); // -1
/// ```
int? operator -(int? other) => (this == null || other == null) ? null : this! - other;

/// Returns the product of this and [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a * b;
///
/// foo(1, null); // null
/// foo(1, 2); // 2
/// ```
int? operator *(int? other) => (this == null || other == null) ? null : this! * other;

/// Returns the remainder of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// int? foo(int? a, int? b) => a % b;
///
/// foo(1, null); // null
/// foo(1, 2); // 1
/// ```
int? operator %(int? other) => (this == null || other == null) ? null : this! % other;

/// Returns the negation of this, or `null` if this is `null`.
///
/// ```dart
/// int? foo(int? a) => -a;
///
/// foo(null); // null
/// foo(1); // -1
/// ```
int? operator -() => this == null ? null : -this!;

}

/// Provides functions for working with nullable [double]s, specifically their operator overloads which do not work with
/// the null-aware operator.
///
/// ## Note:
/// Chaining functions provided by this extension is not recommended in performance sensitive contexts due to the
/// repeated null checks with each function call.
extension NullableDoubles on double? {

/// Returns the sum of this and [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a + b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // 3.0
/// ```
double? operator +(double? other) => (this == null || other == null) ? null : this! + other;

/// Returns the difference of this and [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a - b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // -1.0
/// ```
double? operator -(double? other) => (this == null || other == null) ? null : this! - other;

/// Returns the product of this and [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a * b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // 2.0
/// ```
double? operator *(double? other) => (this == null || other == null) ? null : this! * other;

/// Returns the remainder of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a % b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // 1.0
/// ```
double? operator %(double? other) => (this == null || other == null) ? null : this! % other;

/// Returns the quotient of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a / b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // 0.5
/// ```
double? operator /(double? other) => (this == null || other == null) ? null : this! / other;

/// Returns the integer quotient of this divided by [other], or `null` if either is `null`.
///
/// ```dart
/// double? foo(double? a, double? b) => a ~/ b;
///
/// foo(1.0, null); // null
/// foo(1.0, 2.0); // 0
/// ```
int? operator ~/(double? other) => (this == null || other == null) ? null : this! ~/ other;

/// Returns the negation of this, or `null` if this is `null`.
///
/// ```dart
/// double? foo(double? a) => -a;
///
/// foo(null); // null
/// foo(1.0); // -1.0
/// ```
double? operator -() => this == null ? null : -this!;

}
Loading

0 comments on commit 3bf7d55

Please sign in to comment.