Jonatas Borges

update to 4.0

1 -## [4.0.0-nullsafety.2] 1 +## [4.0.0]
2 - Added append function to StateMixin. Now is possible track loading, success and error handle of your application with ONE LINE OF CODE. Ex: append(()=> api.getUser); 2 - Added append function to StateMixin. Now is possible track loading, success and error handle of your application with ONE LINE OF CODE. Ex: append(()=> api.getUser);
3 -  
4 -## [4.0.0-nullsafety.0]  
5 - Migrate to null-safety 3 - Migrate to null-safety
6 - Added ScrollMixin to controllers 4 - Added ScrollMixin to controllers
7 - Added loadingMore status to RxStatus 5 - Added loadingMore status to RxStatus
@@ -28,7 +28,7 @@ dependencies: @@ -28,7 +28,7 @@ dependencies:
28 # Use with the CupertinoIcons class for iOS style icons. 28 # Use with the CupertinoIcons class for iOS style icons.
29 get: 29 get:
30 path: ../ 30 path: ../
31 - get_test: ^3.13.3 31 + #get_test: ^3.13.3
32 32
33 dependency_overrides: 33 dependency_overrides:
34 get: 34 get:
@@ -87,7 +87,7 @@ void main() { @@ -87,7 +87,7 @@ void main() {
87 }); 87 });
88 88
89 test('ever', () async { 89 test('ever', () async {
90 - RxString count = ''.obs; 90 + final count = ''.obs;
91 var result = ''; 91 var result = '';
92 ever<String>(count, (value) { 92 ever<String>(count, (value) {
93 result = value; 93 result = value;
@@ -1011,7 +1011,7 @@ you can only use widgets and widget functions here'''; @@ -1011,7 +1011,7 @@ you can only use widgets and widget functions here''';
1011 return key; 1011 return key;
1012 } 1012 }
1013 1013
1014 - GlobalKey<NavigatorState>? nestedKey(int key) { 1014 + GlobalKey<NavigatorState>? nestedKey(dynamic key) {
1015 keys.putIfAbsent(key, () => GlobalKey<NavigatorState>()); 1015 keys.putIfAbsent(key, () => GlobalKey<NavigatorState>());
1016 return keys[key]; 1016 return keys[key];
1017 } 1017 }
@@ -1158,7 +1158,7 @@ Since version 2.8 it is possible to access the properties @@ -1158,7 +1158,7 @@ Since version 2.8 it is possible to access the properties
1158 1158
1159 GlobalKey<NavigatorState>? get key => getxController.key; 1159 GlobalKey<NavigatorState>? get key => getxController.key;
1160 1160
1161 - Map<int, GlobalKey<NavigatorState>> get keys => getxController.keys; 1161 + Map<dynamic, GlobalKey<NavigatorState>> get keys => getxController.keys;
1162 1162
1163 GetMaterialController get rootController => getxController; 1163 GetMaterialController get rootController => getxController;
1164 1164
@@ -310,3 +310,64 @@ class GetMaterialApp extends StatelessWidget { @@ -310,3 +310,64 @@ class GetMaterialApp extends StatelessWidget {
310 // actions: actions, 310 // actions: actions,
311 )); 311 ));
312 } 312 }
  313 +
  314 +class GetNavigator extends StatelessWidget {
  315 + final List<GetPage> getPages;
  316 +
  317 + const GetNavigator(
  318 + {Key? key,
  319 + required this.getPages,
  320 + this.pages = const <Page<dynamic>>[],
  321 + this.onPopPage,
  322 + this.initialRoute,
  323 + this.onGenerateInitialRoutes = Navigator.defaultGenerateInitialRoutes,
  324 + this.onGenerateRoute,
  325 + this.onUnknownRoute,
  326 + this.transitionDelegate = const DefaultTransitionDelegate<dynamic>(),
  327 + this.reportsRouteUpdateToEngine = false,
  328 + this.observers = const <NavigatorObserver>[],
  329 + this.restorationScopeId,
  330 + this.unKnownRoute})
  331 + : super(key: key);
  332 +
  333 + final List<Page<dynamic>> pages;
  334 +
  335 + final GetPage? unKnownRoute;
  336 +
  337 + final PopPageCallback? onPopPage;
  338 +
  339 + final TransitionDelegate<dynamic> transitionDelegate;
  340 +
  341 + final String? initialRoute;
  342 +
  343 + final RouteFactory? onGenerateRoute;
  344 +
  345 + final RouteFactory? onUnknownRoute;
  346 +
  347 + final List<NavigatorObserver> observers;
  348 +
  349 + final String? restorationScopeId;
  350 +
  351 + static const String defaultRouteName = '/';
  352 +
  353 + final RouteListFactory onGenerateInitialRoutes;
  354 +
  355 + final bool reportsRouteUpdateToEngine;
  356 +
  357 + @override
  358 + Widget build(Object context) {
  359 + return Navigator(
  360 + pages: getPages,
  361 + onPopPage: onPopPage,
  362 + initialRoute: initialRoute,
  363 + onGenerateInitialRoutes: onGenerateInitialRoutes,
  364 + onGenerateRoute: onGenerateRoute,
  365 + onUnknownRoute: onUnknownRoute,
  366 + transitionDelegate: transitionDelegate,
  367 + reportsRouteUpdateToEngine: reportsRouteUpdateToEngine,
  368 + observers: observers,
  369 + restorationScopeId: restorationScopeId,
  370 + key: Get.nestedKey(key),
  371 + );
  372 + }
  373 +}
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
2 2
  3 +import '../../../get_core/src/get_main.dart';
3 import '../../../get_instance/get_instance.dart'; 4 import '../../../get_instance/get_instance.dart';
4 import '../../get_navigation.dart'; 5 import '../../get_navigation.dart';
5 import 'custom_transition.dart'; 6 import 'custom_transition.dart';
@@ -11,7 +12,8 @@ class PathDecoded { @@ -11,7 +12,8 @@ class PathDecoded {
11 final List<String?> keys; 12 final List<String?> keys;
12 } 13 }
13 14
14 -class GetPage { 15 +class GetPage<T> extends Page<T> {
  16 + @override
15 final String name; 17 final String name;
16 final GetPageBuilder page; 18 final GetPageBuilder page;
17 final bool? popGesture; 19 final bool? popGesture;
@@ -31,6 +33,7 @@ class GetPage { @@ -31,6 +33,7 @@ class GetPage {
31 final List<GetPage>? children; 33 final List<GetPage>? children;
32 final List<GetMiddleware>? middlewares; 34 final List<GetMiddleware>? middlewares;
33 final PathDecoded path; 35 final PathDecoded path;
  36 + final GetPage? unknownRoute;
34 37
35 GetPage({ 38 GetPage({
36 required this.name, 39 required this.name,
@@ -51,6 +54,7 @@ class GetPage { @@ -51,6 +54,7 @@ class GetPage {
51 this.fullscreenDialog = false, 54 this.fullscreenDialog = false,
52 this.children, 55 this.children,
53 this.middlewares, 56 this.middlewares,
  57 + this.unknownRoute,
54 }) : path = _nameToRegex(name); 58 }) : path = _nameToRegex(name);
55 59
56 static PathDecoded _nameToRegex(String path) { 60 static PathDecoded _nameToRegex(String path) {
@@ -74,7 +78,7 @@ class GetPage { @@ -74,7 +78,7 @@ class GetPage {
74 return PathDecoded(RegExp('^$stringPath\$'), keys); 78 return PathDecoded(RegExp('^$stringPath\$'), keys);
75 } 79 }
76 80
77 - GetPage copyWith({ 81 + GetPage copy({
78 String? name, 82 String? name,
79 GetPageBuilder? page, 83 GetPageBuilder? page,
80 bool? popGesture, 84 bool? popGesture,
@@ -115,4 +119,14 @@ class GetPage { @@ -115,4 +119,14 @@ class GetPage {
115 middlewares: middlewares ?? this.middlewares, 119 middlewares: middlewares ?? this.middlewares,
116 ); 120 );
117 } 121 }
  122 +
  123 + @override
  124 + Object? get arguments => Get.arguments;
  125 +
  126 + @override
  127 + Route<T> createRoute(BuildContext context) {
  128 + return PageRedirect(
  129 + RouteSettings(name: name, arguments: Get.arguments), unknownRoute)
  130 + .page<T>();
  131 + }
118 } 132 }
@@ -165,10 +165,10 @@ class PageRedirect { @@ -165,10 +165,10 @@ class PageRedirect {
165 {this.isUnknown = false, this.route}); 165 {this.isUnknown = false, this.route});
166 166
167 // redirect all pages that needes redirecting 167 // redirect all pages that needes redirecting
168 - GetPageRoute page() { 168 + GetPageRoute<T> page<T>() {
169 while (needRecheck()) {} 169 while (needRecheck()) {}
170 return isUnknown 170 return isUnknown
171 - ? GetPageRoute( 171 + ? GetPageRoute<T>(
172 page: unknownRoute!.page, 172 page: unknownRoute!.page,
173 parameter: unknownRoute!.parameter, 173 parameter: unknownRoute!.parameter,
174 settings: RouteSettings( 174 settings: RouteSettings(
@@ -185,7 +185,7 @@ class PageRedirect { @@ -185,7 +185,7 @@ class PageRedirect {
185 fullscreenDialog: unknownRoute!.fullscreenDialog, 185 fullscreenDialog: unknownRoute!.fullscreenDialog,
186 middlewares: unknownRoute!.middlewares, 186 middlewares: unknownRoute!.middlewares,
187 ) 187 )
188 - : GetPageRoute( 188 + : GetPageRoute<T>(
189 page: route!.page, 189 page: route!.page,
190 parameter: route!.parameter, 190 parameter: route!.parameter,
191 settings: RouteSettings( 191 settings: RouteSettings(
@@ -236,6 +236,8 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> { @@ -236,6 +236,8 @@ abstract class _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> {
236 } 236 }
237 } 237 }
238 238
  239 +extension RxBoolExt on Rx<bool> {}
  240 +
239 /// Rx class for `bool` Type. 241 /// Rx class for `bool` Type.
240 class RxBool extends _RxImpl<bool> { 242 class RxBool extends _RxImpl<bool> {
241 RxBool(bool initial) : super(initial); 243 RxBool(bool initial) : super(initial);
@@ -266,143 +268,12 @@ class RxBool extends _RxImpl<bool> { @@ -266,143 +268,12 @@ class RxBool extends _RxImpl<bool> {
266 } 268 }
267 } 269 }
268 270
269 -/// Rx class for `String` Type.  
270 -class RxString extends _RxImpl<String> implements Comparable<String>, Pattern {  
271 - RxString(String initial) : super(initial);  
272 -  
273 - String operator +(String val) => _value + val;  
274 -  
275 - /// Compares this string to [other].  
276 - @override  
277 - int compareTo(String other) {  
278 - return value.compareTo(other);  
279 - }  
280 -  
281 - /// Returns true if this string ends with [other]. For example:  
282 - ///  
283 - /// 'Dart'.endsWith('t'); // true  
284 - bool endsWith(String other) {  
285 - return value.endsWith(other);  
286 - }  
287 -  
288 - /// Returns true if this string starts with a match of [pattern].  
289 - bool startsWith(Pattern pattern, [int index = 0]) {  
290 - return value.startsWith(pattern, index);  
291 - }  
292 -  
293 - /// Returns the position of the first match of [pattern] in this string  
294 - int indexOf(Pattern pattern, [int start = 0]) {  
295 - return value.indexOf(pattern, start);  
296 - }  
297 -  
298 - /// Returns the starting position of the last match [pattern] in this string,  
299 - /// searching backward starting at [start], inclusive:  
300 - int lastIndexOf(Pattern pattern, [int? start]) {  
301 - return value.lastIndexOf(pattern, start);  
302 - }  
303 -  
304 - /// Returns true if this string is empty.  
305 - bool get isEmpty => value.isEmpty;  
306 -  
307 - /// Returns true if this string is not empty.  
308 - bool get isNotEmpty => !isEmpty;  
309 -  
310 - /// Returns the substring of this string that extends from [startIndex],  
311 - /// inclusive, to [endIndex], exclusive  
312 - String substring(int startIndex, [int? endIndex]) {  
313 - return value.substring(startIndex, endIndex);  
314 - }  
315 -  
316 - /// Returns the string without any leading and trailing whitespace.  
317 - String trim() {  
318 - return value.trim();  
319 - }  
320 -  
321 - /// Returns the string without any leading whitespace.  
322 - ///  
323 - /// As [trim], but only removes leading whitespace.  
324 - String trimLeft() {  
325 - return value.trimLeft();  
326 - }  
327 -  
328 - /// Returns the string without any trailing whitespace.  
329 - ///  
330 - /// As [trim], but only removes trailing whitespace.  
331 - String trimRight() {  
332 - return value.trimRight();  
333 - }  
334 -  
335 - /// Pads this string on the left if it is shorter than [width].  
336 - ///  
337 - /// Return a new string that prepends [padding] onto this string  
338 - /// one time for each position the length is less than [width].  
339 - String padLeft(int width, [String padding = ' ']) {  
340 - return value.padLeft(width, padding);  
341 - }  
342 -  
343 - /// Pads this string on the right if it is shorter than [width].  
344 -  
345 - /// Return a new string that appends [padding] after this string  
346 - /// one time for each position the length is less than [width].  
347 - String padRight(int width, [String padding = ' ']) {  
348 - return value.padRight(width, padding);  
349 - }  
350 -  
351 - /// Returns true if this string contains a match of [other]:  
352 - bool contains(Pattern other, [int startIndex = 0]) {  
353 - return value.contains(other, startIndex);  
354 - }  
355 -  
356 - /// Replaces all substrings that match [from] with [replace].  
357 - String replaceAll(Pattern from, String replace) {  
358 - return value.replaceAll(from, replace);  
359 - }  
360 -  
361 - /// Splits the string at matches of [pattern] and returns a list  
362 - /// of substrings.  
363 - List<String> split(Pattern pattern) {  
364 - return value.split(pattern);  
365 - }  
366 -  
367 - /// Returns an unmodifiable list of the UTF-16 code units of this string.  
368 - List<int> get codeUnits => value.codeUnits;  
369 -  
370 - /// Returns an [Iterable] of Unicode code-points of this string.  
371 - ///  
372 - /// If the string contains surrogate pairs, they are combined and returned  
373 - /// as one integer by this iterator. Unmatched surrogate halves are treated  
374 - /// like valid 16-bit code-units.  
375 - Runes get runes => value.runes;  
376 -  
377 - /// Converts all characters in this string to lower case.  
378 - /// If the string is already in all lower case, this method returns `this`.  
379 - String toLowerCase() {  
380 - return value.toLowerCase();  
381 - }  
382 -  
383 - /// Converts all characters in this string to upper case.  
384 - /// If the string is already in all upper case, this method returns `this`.  
385 - String toUpperCase() {  
386 - return value.toUpperCase();  
387 - }  
388 -  
389 - @override  
390 - Iterable<Match> allMatches(String string, [int start = 0]) {  
391 - return value.allMatches(string, start);  
392 - }  
393 -  
394 - @override  
395 - Match? matchAsPrefix(String string, [int start = 0]) {  
396 - return value.matchAsPrefix(string, start);  
397 - }  
398 -}  
399 -  
400 /// Foundation class used for custom `Types` outside the common native Dart 271 /// Foundation class used for custom `Types` outside the common native Dart
401 /// types. 272 /// types.
402 /// For example, any custom "Model" class, like User().obs will use `Rx` as 273 /// For example, any custom "Model" class, like User().obs will use `Rx` as
403 /// wrapper. 274 /// wrapper.
404 -class Rx<T> extends _RxImpl<T?> {  
405 - Rx([T? initial]) : super(initial); 275 +class Rx<T> extends _RxImpl<T> {
  276 + Rx(T initial) : super(initial);
406 277
407 @override 278 @override
408 dynamic toJson() { 279 dynamic toJson() {
1 part of rx_types; 1 part of rx_types;
2 2
3 -/// Base Rx class for all num Rx's.  
4 -abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {  
5 - _BaseRxNum(T initial) : super(initial);  
6 -  
7 - /// Addition operator. */  
8 - 3 +extension RxNumExt<T extends num> on Rx<T> {
9 /// Multiplication operator. 4 /// Multiplication operator.
10 - num operator *(num other) => value! * other; 5 + num operator *(num other) => value * other;
11 6
12 /// Euclidean modulo operator. 7 /// Euclidean modulo operator.
13 /// 8 ///
@@ -22,10 +17,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -22,10 +17,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
22 /// The sign of the returned value `r` is always positive. 17 /// The sign of the returned value `r` is always positive.
23 /// 18 ///
24 /// See [remainder] for the remainder of the truncating division. 19 /// See [remainder] for the remainder of the truncating division.
25 - num operator %(num other) => value! % other; 20 + num operator %(num other) => value % other;
26 21
27 /// Division operator. 22 /// Division operator.
28 - double operator /(num other) => value! / other; 23 + double operator /(num other) => value / other;
29 24
30 /// Truncating division operator. 25 /// Truncating division operator.
31 /// 26 ///
@@ -34,10 +29,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -34,10 +29,10 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
34 /// 29 ///
35 /// If both operands are [int]s then `a ~/ b` performs the truncating 30 /// If both operands are [int]s then `a ~/ b` performs the truncating
36 /// integer division. 31 /// integer division.
37 - int operator ~/(num other) => value! ~/ other; 32 + int operator ~/(num other) => value ~/ other;
38 33
39 /// Negate operator. 34 /// Negate operator.
40 - num operator -() => -value!; 35 + num operator -() => -value;
41 36
42 /// Returns the remainder of the truncating division of `this` by [other]. 37 /// Returns the remainder of the truncating division of `this` by [other].
43 /// 38 ///
@@ -45,40 +40,40 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -45,40 +40,40 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
45 /// `this == (this ~/ other) * other + r`. 40 /// `this == (this ~/ other) * other + r`.
46 /// As a consequence the remainder `r` has the same sign as the divider 41 /// As a consequence the remainder `r` has the same sign as the divider
47 /// `this`. 42 /// `this`.
48 - num remainder(num other) => value!.remainder(other); 43 + num remainder(num other) => value.remainder(other);
49 44
50 /// Relational less than operator. 45 /// Relational less than operator.
51 - bool operator <(num other) => value! < other; 46 + bool operator <(num other) => value < other;
52 47
53 /// Relational less than or equal operator. 48 /// Relational less than or equal operator.
54 - bool operator <=(num other) => value! <= other; 49 + bool operator <=(num other) => value <= other;
55 50
56 /// Relational greater than operator. 51 /// Relational greater than operator.
57 - bool operator >(num other) => value! > other; 52 + bool operator >(num other) => value > other;
58 53
59 /// Relational greater than or equal operator. 54 /// Relational greater than or equal operator.
60 - bool operator >=(num other) => value! >= other; 55 + bool operator >=(num other) => value >= other;
61 56
62 /// True if the number is the double Not-a-Number value; otherwise, false. 57 /// True if the number is the double Not-a-Number value; otherwise, false.
63 - bool get isNaN => value!.isNaN; 58 + bool get isNaN => value.isNaN;
64 59
65 /// True if the number is negative; otherwise, false. 60 /// True if the number is negative; otherwise, false.
66 /// 61 ///
67 /// Negative numbers are those less than zero, and the double `-0.0`. 62 /// Negative numbers are those less than zero, and the double `-0.0`.
68 - bool get isNegative => value!.isNegative; 63 + bool get isNegative => value.isNegative;
69 64
70 /// True if the number is positive infinity or negative infinity; otherwise, 65 /// True if the number is positive infinity or negative infinity; otherwise,
71 /// false. 66 /// false.
72 - bool get isInfinite => value!.isInfinite; 67 + bool get isInfinite => value.isInfinite;
73 68
74 /// True if the number is finite; otherwise, false. 69 /// True if the number is finite; otherwise, false.
75 /// 70 ///
76 /// The only non-finite numbers are NaN, positive infinity, and 71 /// The only non-finite numbers are NaN, positive infinity, and
77 /// negative infinity. 72 /// negative infinity.
78 - bool get isFinite => value!.isFinite; 73 + bool get isFinite => value.isFinite;
79 74
80 /// Returns the absolute value of this [num]. 75 /// Returns the absolute value of this [num].
81 - num abs() => value!.abs(); 76 + num abs() => value.abs();
82 77
83 /// Returns minus one, zero or plus one depending on the sign and 78 /// Returns minus one, zero or plus one depending on the sign and
84 /// numerical value of the number. 79 /// numerical value of the number.
@@ -96,7 +91,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -96,7 +91,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
96 /// n == n.sign * n.abs() 91 /// n == n.sign * n.abs()
97 /// 92 ///
98 /// for all numbers `n` (except NaN, because NaN isn't `==` to itself). 93 /// for all numbers `n` (except NaN, because NaN isn't `==` to itself).
99 - num get sign => value!.sign; 94 + num get sign => value.sign;
100 95
101 /// Returns the integer closest to `this`. 96 /// Returns the integer closest to `this`.
102 /// 97 ///
@@ -104,23 +99,23 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -104,23 +99,23 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
104 /// `(3.5).round() == 4` and `(-3.5).round() == -4`. 99 /// `(3.5).round() == 4` and `(-3.5).round() == -4`.
105 /// 100 ///
106 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 101 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
107 - int round() => value!.round(); 102 + int round() => value.round();
108 103
109 /// Returns the greatest integer no greater than `this`. 104 /// Returns the greatest integer no greater than `this`.
110 /// 105 ///
111 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 106 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
112 - int floor() => value!.floor(); 107 + int floor() => value.floor();
113 108
114 /// Returns the least integer no smaller than `this`. 109 /// Returns the least integer no smaller than `this`.
115 /// 110 ///
116 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 111 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
117 - int ceil() => value!.ceil(); 112 + int ceil() => value.ceil();
118 113
119 /// Returns the integer obtained by discarding any fractional 114 /// Returns the integer obtained by discarding any fractional
120 /// digits from `this`. 115 /// digits from `this`.
121 /// 116 ///
122 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 117 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
123 - int truncate() => value!.truncate(); 118 + int truncate() => value.truncate();
124 119
125 /// Returns the double integer value closest to `this`. 120 /// Returns the double integer value closest to `this`.
126 /// 121 ///
@@ -138,7 +133,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -138,7 +133,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
138 /// The result is always a double. 133 /// The result is always a double.
139 /// If this is a numerically large integer, the result may be an infinite 134 /// If this is a numerically large integer, the result may be an infinite
140 /// double. 135 /// double.
141 - double roundToDouble() => value!.roundToDouble(); 136 + double roundToDouble() => value.roundToDouble();
142 137
143 /// Returns the greatest double integer value no greater than `this`. 138 /// Returns the greatest double integer value no greater than `this`.
144 /// 139 ///
@@ -151,7 +146,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -151,7 +146,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
151 /// The result is always a double. 146 /// The result is always a double.
152 /// If this is a numerically large integer, the result may be an infinite 147 /// If this is a numerically large integer, the result may be an infinite
153 /// double. 148 /// double.
154 - double floorToDouble() => value!.floorToDouble(); 149 + double floorToDouble() => value.floorToDouble();
155 150
156 /// Returns the least double integer value no smaller than `this`. 151 /// Returns the least double integer value no smaller than `this`.
157 /// 152 ///
@@ -164,7 +159,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -164,7 +159,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
164 /// The result is always a double. 159 /// The result is always a double.
165 /// If this is a numerically large integer, the result may be an infinite 160 /// If this is a numerically large integer, the result may be an infinite
166 /// double. 161 /// double.
167 - double ceilToDouble() => value!.ceilToDouble(); 162 + double ceilToDouble() => value.ceilToDouble();
168 163
169 /// Returns the double integer value obtained by discarding any fractional 164 /// Returns the double integer value obtained by discarding any fractional
170 /// digits from the double value of `this`. 165 /// digits from the double value of `this`.
@@ -179,7 +174,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -179,7 +174,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
179 /// The result is always a double. 174 /// The result is always a double.
180 /// If this is a numerically large integer, the result may be an infinite 175 /// If this is a numerically large integer, the result may be an infinite
181 /// double. 176 /// double.
182 - double truncateToDouble() => value!.truncateToDouble(); 177 + double truncateToDouble() => value.truncateToDouble();
183 178
184 /// Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit]. 179 /// Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
185 /// 180 ///
@@ -190,17 +185,17 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -190,17 +185,17 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
190 /// The arguments [lowerLimit] and [upperLimit] must form a valid range where 185 /// The arguments [lowerLimit] and [upperLimit] must form a valid range where
191 /// `lowerLimit.compareTo(upperLimit) <= 0`. 186 /// `lowerLimit.compareTo(upperLimit) <= 0`.
192 num clamp(num lowerLimit, num upperLimit) => 187 num clamp(num lowerLimit, num upperLimit) =>
193 - value!.clamp(lowerLimit, upperLimit); 188 + value.clamp(lowerLimit, upperLimit);
194 189
195 /// Truncates this [num] to an integer and returns the result as an [int]. */ 190 /// Truncates this [num] to an integer and returns the result as an [int]. */
196 - int toInt() => value!.toInt(); 191 + int toInt() => value.toInt();
197 192
198 /// Return this [num] as a [double]. 193 /// Return this [num] as a [double].
199 /// 194 ///
200 /// If the number is not representable as a [double], an 195 /// If the number is not representable as a [double], an
201 /// approximation is returned. For numerically large integers, the 196 /// approximation is returned. For numerically large integers, the
202 /// approximation may be infinite. 197 /// approximation may be infinite.
203 - double toDouble() => value!.toDouble(); 198 + double toDouble() => value.toDouble();
204 199
205 /// Returns a decimal-point string-representation of `this`. 200 /// Returns a decimal-point string-representation of `this`.
206 /// 201 ///
@@ -225,7 +220,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -225,7 +220,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
225 /// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000 220 /// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
226 /// 5.25.toStringAsFixed(0); // 5 221 /// 5.25.toStringAsFixed(0); // 5
227 String toStringAsFixed(int fractionDigits) => 222 String toStringAsFixed(int fractionDigits) =>
228 - value!.toStringAsFixed(fractionDigits); 223 + value.toStringAsFixed(fractionDigits);
229 224
230 /// Returns an exponential string-representation of `this`. 225 /// Returns an exponential string-representation of `this`.
231 /// 226 ///
@@ -246,7 +241,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -246,7 +241,7 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
246 /// 123456.toStringAsExponential(3); // 1.235e+5 241 /// 123456.toStringAsExponential(3); // 1.235e+5
247 /// 123.toStringAsExponential(0); // 1e+2 242 /// 123.toStringAsExponential(0); // 1e+2
248 String toStringAsExponential([int? fractionDigits]) => 243 String toStringAsExponential([int? fractionDigits]) =>
249 - value!.toStringAsExponential(fractionDigits); 244 + value.toStringAsExponential(fractionDigits);
250 245
251 /// Converts `this` to a double and returns a string representation with 246 /// Converts `this` to a double and returns a string representation with
252 /// exactly [precision] significant digits. 247 /// exactly [precision] significant digits.
@@ -265,72 +260,137 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> { @@ -265,72 +260,137 @@ abstract class _BaseRxNum<T extends num?> extends _RxImpl<T> {
265 /// 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7 260 /// 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
266 /// 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000 261 /// 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000
267 String toStringAsPrecision(int precision) => 262 String toStringAsPrecision(int precision) =>
268 - value!.toStringAsPrecision(precision); 263 + value.toStringAsPrecision(precision);
269 } 264 }
270 265
271 -class RxNum extends _BaseRxNum<num> {  
272 - RxNum(num initial) : super(initial); 266 +extension RxnNumExt<T extends num> on Rx<T?> {
  267 + /// Multiplication operator.
  268 + num? operator *(num other) {
  269 + if (value != null) {
  270 + return value! * other;
  271 + }
  272 + }
273 273
274 - num? operator +(num other) {  
275 - value += other;  
276 - return value; 274 + /// Euclidean modulo operator.
  275 + ///
  276 + /// Returns the remainder of the Euclidean division. The Euclidean division of
  277 + /// two integers `a` and `b` yields two integers `q` and `r` such that
  278 + /// `a == b * q + r` and `0 <= r < b.abs()`.
  279 + ///
  280 + /// The Euclidean division is only defined for integers, but can be easily
  281 + /// extended to work with doubles. In that case `r` may have a non-integer
  282 + /// value, but it still verifies `0 <= r < |b|`.
  283 + ///
  284 + /// The sign of the returned value `r` is always positive.
  285 + ///
  286 + /// See [remainder] for the remainder of the truncating division.
  287 + num? operator %(num other) {
  288 + if (value != null) {
  289 + return value! % other;
  290 + }
277 } 291 }
278 292
279 - /// Subtraction operator.  
280 - num? operator -(num other) {  
281 - value -= other;  
282 - return value; 293 + /// Division operator.
  294 + double? operator /(num other) {
  295 + if (value != null) {
  296 + return value! / other;
  297 + }
283 } 298 }
284 -}  
285 299
286 -class RxDouble extends _BaseRxNum<double?> {  
287 - RxDouble([double? initial]) : super(initial); 300 + /// Truncating division operator.
  301 + ///
  302 + /// If either operand is a [double] then the result of the truncating division
  303 + /// `a ~/ b` is equivalent to `(a / b).truncate().toInt()`.
  304 + ///
  305 + /// If both operands are [int]s then `a ~/ b` performs the truncating
  306 + /// integer division.
  307 + int? operator ~/(num other) {
  308 + if (value != null) {
  309 + return value! ~/ other;
  310 + }
  311 + }
288 312
289 - /// Addition operator.  
290 - RxDouble operator +(num other) {  
291 - value = value! + other;  
292 - return this; 313 + /// Negate operator.
  314 + num? operator -() {
  315 + if (value != null) {
  316 + return -value!;
  317 + }
293 } 318 }
294 319
295 - /// Subtraction operator.  
296 - RxDouble operator -(num other) {  
297 - value = value! - other;  
298 - return this; 320 + /// Returns the remainder of the truncating division of `this` by [other].
  321 + ///
  322 + /// The result `r` of this operation satisfies:
  323 + /// `this == (this ~/ other) * other + r`.
  324 + /// As a consequence the remainder `r` has the same sign as the divider
  325 + /// `this`.
  326 + num? remainder(num other) => value?.remainder(other);
  327 +
  328 + /// Relational less than operator.
  329 + bool? operator <(num other) {
  330 + if (value != null) {
  331 + return value! < other;
  332 + }
299 } 333 }
300 334
301 - /// Multiplication operator.  
302 - @override  
303 - double operator *(num other) => value! * other; 335 + /// Relational less than or equal operator.
  336 + bool? operator <=(num other) {
  337 + if (value != null) {
  338 + return value! <= other;
  339 + }
  340 + }
304 341
305 - @override  
306 - double operator %(num other) => value! % other; 342 + /// Relational greater than operator.
  343 + bool? operator >(num other) {
  344 + if (value != null) {
  345 + return value! > other;
  346 + }
  347 + }
307 348
308 - /// Division operator.  
309 - @override  
310 - double operator /(num other) => value! / other; 349 + /// Relational greater than or equal operator.
  350 + bool? operator >=(num other) {
  351 + if (value != null) {
  352 + return value! >= other;
  353 + }
  354 + }
311 355
312 - /// Truncating division operator. 356 + /// True if the number is the double Not-a-Number value; otherwise, false.
  357 + bool? get isNaN => value?.isNaN;
  358 +
  359 + /// True if the number is negative; otherwise, false.
313 /// 360 ///
314 - /// The result of the truncating division `a ~/ b` is equivalent to  
315 - /// `(a / b).truncate()`.  
316 - @override  
317 - int operator ~/(num other) => value! ~/ other; 361 + /// Negative numbers are those less than zero, and the double `-0.0`.
  362 + bool? get isNegative => value?.isNegative;
318 363
319 - /// Negate operator. */  
320 - @override  
321 - double operator -() => -value!; 364 + /// True if the number is positive infinity or negative infinity; otherwise,
  365 + /// false.
  366 + bool? get isInfinite => value?.isInfinite;
322 367
323 - /// Returns the absolute value of this [double].  
324 - @override  
325 - double abs() => value!.abs(); 368 + /// True if the number is finite; otherwise, false.
  369 + ///
  370 + /// The only non-finite numbers are NaN, positive infinity, and
  371 + /// negative infinity.
  372 + bool? get isFinite => value?.isFinite;
326 373
327 - /// Returns the sign of the double's numerical value. 374 + /// Returns the absolute value of this [num].
  375 + num? abs() => value?.abs();
  376 +
  377 + /// Returns minus one, zero or plus one depending on the sign and
  378 + /// numerical value of the number.
328 /// 379 ///
329 - /// Returns -1.0 if the value is less than zero,  
330 - /// +1.0 if the value is greater than zero,  
331 - /// and the value itself if it is -0.0, 0.0 or NaN.  
332 - @override  
333 - double get sign => value!.sign; 380 + /// Returns minus one if the number is less than zero,
  381 + /// plus one if the number is greater than zero,
  382 + /// and zero if the number is equal to zero.
  383 + ///
  384 + /// Returns NaN if the number is the double NaN value.
  385 + ///
  386 + /// Returns a number of the same type as this number.
  387 + /// For doubles, `-0.0.sign == -0.0`.
  388 + /// The result satisfies:
  389 + ///
  390 + /// n == n.sign * n.abs()
  391 + ///
  392 + /// for all numbers `n` (except NaN, because NaN isn't `==` to itself).
  393 + num? get sign => value?.sign;
334 394
335 /// Returns the integer closest to `this`. 395 /// Returns the integer closest to `this`.
336 /// 396 ///
@@ -338,163 +398,547 @@ class RxDouble extends _BaseRxNum<double?> { @@ -338,163 +398,547 @@ class RxDouble extends _BaseRxNum<double?> {
338 /// `(3.5).round() == 4` and `(-3.5).round() == -4`. 398 /// `(3.5).round() == 4` and `(-3.5).round() == -4`.
339 /// 399 ///
340 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 400 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
341 - @override  
342 - int round() => value!.round(); 401 + int? round() => value?.round();
343 402
344 /// Returns the greatest integer no greater than `this`. 403 /// Returns the greatest integer no greater than `this`.
345 /// 404 ///
346 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 405 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
347 - @override  
348 - int floor() => value!.floor(); 406 + int? floor() => value?.floor();
349 407
350 /// Returns the least integer no smaller than `this`. 408 /// Returns the least integer no smaller than `this`.
351 /// 409 ///
352 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 410 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
353 - @override  
354 - int ceil() => value!.ceil(); 411 + int? ceil() => value?.ceil();
355 412
356 /// Returns the integer obtained by discarding any fractional 413 /// Returns the integer obtained by discarding any fractional
357 /// digits from `this`. 414 /// digits from `this`.
358 /// 415 ///
359 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError]. 416 /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
360 - @override  
361 - int truncate() => value!.truncate(); 417 + int? truncate() => value?.truncate();
362 418
363 - /// Returns the integer double value closest to `this`. 419 + /// Returns the double integer value closest to `this`.
364 /// 420 ///
365 /// Rounds away from zero when there is no closest integer: 421 /// Rounds away from zero when there is no closest integer:
366 /// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`. 422 /// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
367 /// 423 ///
368 - /// If this is already an integer valued double, including `-0.0`, or it is  
369 - /// not a finite value, the value is returned unmodified. 424 + /// If this is already an integer valued double, including `-0.0`, or it is a
  425 + /// non-finite double value, the value is returned unmodified.
370 /// 426 ///
371 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`, 427 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
372 /// and `-0.0` is therefore considered closer to negative numbers than `0.0`. 428 /// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
373 /// This means that for a value, `d` in the range `-0.5 < d < 0.0`, 429 /// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
374 /// the result is `-0.0`. 430 /// the result is `-0.0`.
375 - @override  
376 - double roundToDouble() => value!.roundToDouble(); 431 + ///
  432 + /// The result is always a double.
  433 + /// If this is a numerically large integer, the result may be an infinite
  434 + /// double.
  435 + double? roundToDouble() => value?.roundToDouble();
377 436
378 - /// Returns the greatest integer double value no greater than `this`. 437 + /// Returns the greatest double integer value no greater than `this`.
379 /// 438 ///
380 - /// If this is already an integer valued double, including `-0.0`, or it is  
381 - /// not a finite value, the value is returned unmodified. 439 + /// If this is already an integer valued double, including `-0.0`, or it is a
  440 + /// non-finite double value, the value is returned unmodified.
382 /// 441 ///
383 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`. 442 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
384 /// A number `d` in the range `0.0 < d < 1.0` will return `0.0`. 443 /// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
385 - @override  
386 - double floorToDouble() => value!.floorToDouble(); 444 + ///
  445 + /// The result is always a double.
  446 + /// If this is a numerically large integer, the result may be an infinite
  447 + /// double.
  448 + double? floorToDouble() => value?.floorToDouble();
387 449
388 - /// Returns the least integer double value no smaller than `this`. 450 + /// Returns the least double integer value no smaller than `this`.
389 /// 451 ///
390 - /// If this is already an integer valued double, including `-0.0`, or it is  
391 - /// not a finite value, the value is returned unmodified. 452 + /// If this is already an integer valued double, including `-0.0`, or it is a
  453 + /// non-finite double value, the value is returned unmodified.
392 /// 454 ///
393 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`. 455 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
394 /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`. 456 /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
395 - @override  
396 - double ceilToDouble() => value!.ceilToDouble(); 457 + ///
  458 + /// The result is always a double.
  459 + /// If this is a numerically large integer, the result may be an infinite
  460 + /// double.
  461 + double? ceilToDouble() => value?.ceilToDouble();
397 462
398 - /// Returns the integer double value obtained by discarding any fractional  
399 - /// digits from `this`. 463 + /// Returns the double integer value obtained by discarding any fractional
  464 + /// digits from the double value of `this`.
400 /// 465 ///
401 - /// If this is already an integer valued double, including `-0.0`, or it is  
402 - /// not a finite value, the value is returned unmodified. 466 + /// If this is already an integer valued double, including `-0.0`, or it is a
  467 + /// non-finite double value, the value is returned unmodified.
403 /// 468 ///
404 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`. 469 /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
405 /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and 470 /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
406 /// in the range `0.0 < d < 1.0` it will return 0.0. 471 /// in the range `0.0 < d < 1.0` it will return 0.0.
407 - @override  
408 - double truncateToDouble() => value!.truncateToDouble();  
409 -}  
410 -  
411 -class RxInt extends _BaseRxNum<int> {  
412 - RxInt(int initial) : super(initial);  
413 -  
414 - /// Addition operator.  
415 - RxInt operator +(int other) {  
416 - value = value + other;  
417 - return this;  
418 - }  
419 -  
420 - /// Subtraction operator.  
421 - RxInt operator -(int other) {  
422 - value = value - other;  
423 - return this;  
424 - }  
425 -  
426 - /// Bit-wise and operator.  
427 - ///  
428 - /// Treating both `this` and [other] as sufficiently large two's component  
429 - /// integers, the result is a number with only the bits set that are set in  
430 - /// both `this` and [other]  
431 /// 472 ///
432 - /// If both operands are negative, the result is negative, otherwise  
433 - /// the result is non-negative.  
434 - int operator &(int other) => value & other; 473 + /// The result is always a double.
  474 + /// If this is a numerically large integer, the result may be an infinite
  475 + /// double.
  476 + double? truncateToDouble() => value?.truncateToDouble();
435 477
436 - /// Bit-wise or operator. 478 + /// Returns this [num] clamped to be in the range [lowerLimit]-[upperLimit].
437 /// 479 ///
438 - /// Treating both `this` and [other] as sufficiently large two's component  
439 - /// integers, the result is a number with the bits set that are set in either  
440 - /// of `this` and [other] 480 + /// The comparison is done using [compareTo] and therefore takes `-0.0` into
  481 + /// account. This also implies that [double.nan] is treated as the maximal
  482 + /// double value.
441 /// 483 ///
442 - /// If both operands are non-negative, the result is non-negative,  
443 - /// otherwise the result is negative.  
444 - int operator |(int other) => value | other; 484 + /// The arguments [lowerLimit] and [upperLimit] must form a valid range where
  485 + /// `lowerLimit.compareTo(upperLimit) <= 0`.
  486 + num? clamp(num lowerLimit, num upperLimit) =>
  487 + value?.clamp(lowerLimit, upperLimit);
445 488
446 - /// Bit-wise exclusive-or operator.  
447 - ///  
448 - /// Treating both `this` and [other] as sufficiently large two's component  
449 - /// integers, the result is a number with the bits set that are set in one,  
450 - /// but not both, of `this` and [other]  
451 - ///  
452 - /// If the operands have the same sign, the result is non-negative,  
453 - /// otherwise the result is negative.  
454 - int operator ^(int other) => value ^ other; 489 + /// Truncates this [num] to an integer and returns the result as an [int]. */
  490 + int? toInt() => value?.toInt();
455 491
456 - /// The bit-wise negate operator.  
457 - ///  
458 - /// Treating `this` as a sufficiently large two's component integer,  
459 - /// the result is a number with the opposite bits set. 492 + /// Return this [num] as a [double].
460 /// 493 ///
461 - /// This maps any integer `x` to `-x - 1`.  
462 - int operator ~() => ~value; 494 + /// If the number is not representable as a [double], an
  495 + /// approximation is returned. For numerically large integers, the
  496 + /// approximation may be infinite.
  497 + double? toDouble() => value?.toDouble();
463 498
464 - /// Shift the bits of this integer to the left by [shiftAmount]. 499 + /// Returns a decimal-point string-representation of `this`.
465 /// 500 ///
466 - /// Shifting to the left makes the number larger, effectively multiplying  
467 - /// the number by `pow(2, shiftIndex)`. 501 + /// Converts `this` to a [double] before computing the string representation.
468 /// 502 ///
469 - /// There is no limit on the size of the result. It may be relevant to  
470 - /// limit intermediate values by using the "and" operator with a suitable  
471 - /// mask. 503 + /// If the absolute value of `this` is greater or equal to `10^21` then this
  504 + /// methods returns an exponential representation computed by
  505 + /// `this.toStringAsExponential()`. Otherwise the result
  506 + /// is the closest string representation with exactly [fractionDigits] digits
  507 + /// after the decimal point. If [fractionDigits] equals 0 then the decimal
  508 + /// point is omitted.
472 /// 509 ///
473 - /// It is an error if [shiftAmount] is negative.  
474 - int operator <<(int shiftAmount) => value << shiftAmount;  
475 -  
476 - /// Shift the bits of this integer to the right by [shiftAmount]. 510 + /// The parameter [fractionDigits] must be an integer satisfying:
  511 + /// `0 <= fractionDigits <= 20`.
477 /// 512 ///
478 - /// Shifting to the right makes the number smaller and drops the least  
479 - /// significant bits, effectively doing an integer division by  
480 - ///`pow(2, shiftIndex)`. 513 + /// Examples:
481 /// 514 ///
482 - /// It is an error if [shiftAmount] is negative.  
483 - int operator >>(int shiftAmount) => value >> shiftAmount; 515 + /// 1.toStringAsFixed(3); // 1.000
  516 + /// (4321.12345678).toStringAsFixed(3); // 4321.123
  517 + /// (4321.12345678).toStringAsFixed(5); // 4321.12346
  518 + /// 123456789012345.toStringAsFixed(3); // 123456789012345.000
  519 + /// 10000000000000000.toStringAsFixed(4); // 10000000000000000.0000
  520 + /// 5.25.toStringAsFixed(0); // 5
  521 + String? toStringAsFixed(int fractionDigits) =>
  522 + value?.toStringAsFixed(fractionDigits);
484 523
485 - /// Returns this integer to the power of [exponent] modulo [modulus]. 524 + /// Returns an exponential string-representation of `this`.
486 /// 525 ///
487 - /// The [exponent] must be non-negative and [modulus] must be  
488 - /// positive.  
489 - int modPow(int exponent, int modulus) => value.modPow(exponent, modulus);  
490 -  
491 - /// Returns the modular multiplicative inverse of this integer  
492 - /// modulo [modulus]. 526 + /// Converts `this` to a [double] before computing the string representation.
493 /// 527 ///
494 - /// The [modulus] must be positive. 528 + /// If [fractionDigits] is given then it must be an integer satisfying:
  529 + /// `0 <= fractionDigits <= 20`. In this case the string contains exactly
  530 + /// [fractionDigits] after the decimal point. Otherwise, without the
  531 + /// parameter, the returned string uses the shortest number of digits that
  532 + /// accurately represent [this].
495 /// 533 ///
496 - /// It is an error if no modular inverse exists.  
497 - int modInverse(int modulus) => value.modInverse(modulus); 534 + /// If [fractionDigits] equals 0 then the decimal point is omitted.
  535 + /// Examples:
  536 + ///
  537 + /// 1.toStringAsExponential(); // 1e+0
  538 + /// 1.toStringAsExponential(3); // 1.000e+0
  539 + /// 123456.toStringAsExponential(); // 1.23456e+5
  540 + /// 123456.toStringAsExponential(3); // 1.235e+5
  541 + /// 123.toStringAsExponential(0); // 1e+2
  542 + String? toStringAsExponential([int? fractionDigits]) =>
  543 + value?.toStringAsExponential(fractionDigits);
  544 +
  545 + /// Converts `this` to a double and returns a string representation with
  546 + /// exactly [precision] significant digits.
  547 + ///
  548 + /// The parameter [precision] must be an integer satisfying:
  549 + /// `1 <= precision <= 21`.
  550 + ///
  551 + /// Examples:
  552 + ///
  553 + /// 1.toStringAsPrecision(2); // 1.0
  554 + /// 1e15.toStringAsPrecision(3); // 1.00e+15
  555 + /// 1234567.toStringAsPrecision(3); // 1.23e+6
  556 + /// 1234567.toStringAsPrecision(9); // 1234567.00
  557 + /// 12345678901234567890.toStringAsPrecision(20); // 12345678901234567168
  558 + /// 12345678901234567890.toStringAsPrecision(14); // 1.2345678901235e+19
  559 + /// 0.00000012345.toStringAsPrecision(15); // 1.23450000000000e-7
  560 + /// 0.0000012345.toStringAsPrecision(15); // 0.00000123450000000000
  561 + String? toStringAsPrecision(int precision) =>
  562 + value?.toStringAsPrecision(precision);
  563 +}
  564 +
  565 +class RxNum extends Rx<num> {
  566 + RxNum(num initial) : super(initial);
  567 +
  568 + num operator +(num other) {
  569 + value += other;
  570 + return value;
  571 + }
  572 +
  573 + /// Subtraction operator.
  574 + num operator -(num other) {
  575 + value -= other;
  576 + return value;
  577 + }
  578 +}
  579 +
  580 +class RxnNum extends Rx<num?> {
  581 + RxnNum(num initial) : super(initial);
  582 +
  583 + num? operator +(num other) {
  584 + if (value != null) {
  585 + value = value! + other;
  586 + return value;
  587 + }
  588 + }
  589 +
  590 + /// Subtraction operator.
  591 + num? operator -(num other) {
  592 + if (value != null) {
  593 + value = value! - other;
  594 + return value;
  595 + }
  596 + }
  597 +}
  598 +
  599 +extension RxDoubleExt on Rx<double> {
  600 + /// Addition operator.
  601 + Rx<double> operator +(num other) {
  602 + value = value + other;
  603 + return this;
  604 + }
  605 +
  606 + /// Subtraction operator.
  607 + Rx<double> operator -(num other) {
  608 + value = value - other;
  609 + return this;
  610 + }
  611 +
  612 + /// Multiplication operator.
  613 + double operator *(num other) => value * other;
  614 +
  615 + double operator %(num other) => value % other;
  616 +
  617 + /// Division operator.
  618 + double operator /(num other) => value / other;
  619 +
  620 + /// Truncating division operator.
  621 + ///
  622 + /// The result of the truncating division `a ~/ b` is equivalent to
  623 + /// `(a / b).truncate()`.
  624 + int operator ~/(num other) => value ~/ other;
  625 +
  626 + /// Negate operator. */
  627 + double operator -() => -value;
  628 +
  629 + /// Returns the absolute value of this [double].
  630 + double abs() => value.abs();
  631 +
  632 + /// Returns the sign of the double's numerical value.
  633 + ///
  634 + /// Returns -1.0 if the value is less than zero,
  635 + /// +1.0 if the value is greater than zero,
  636 + /// and the value itself if it is -0.0, 0.0 or NaN.
  637 + double get sign => value.sign;
  638 +
  639 + /// Returns the integer closest to `this`.
  640 + ///
  641 + /// Rounds away from zero when there is no closest integer:
  642 + /// `(3.5).round() == 4` and `(-3.5).round() == -4`.
  643 + ///
  644 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  645 + int round() => value.round();
  646 +
  647 + /// Returns the greatest integer no greater than `this`.
  648 + ///
  649 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  650 + int floor() => value.floor();
  651 +
  652 + /// Returns the least integer no smaller than `this`.
  653 + ///
  654 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  655 + int ceil() => value.ceil();
  656 +
  657 + /// Returns the integer obtained by discarding any fractional
  658 + /// digits from `this`.
  659 + ///
  660 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  661 + int truncate() => value.truncate();
  662 +
  663 + /// Returns the integer double value closest to `this`.
  664 + ///
  665 + /// Rounds away from zero when there is no closest integer:
  666 + /// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
  667 + ///
  668 + /// If this is already an integer valued double, including `-0.0`, or it is
  669 + /// not a finite value, the value is returned unmodified.
  670 + ///
  671 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
  672 + /// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
  673 + /// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
  674 + /// the result is `-0.0`.
  675 + double roundToDouble() => value.roundToDouble();
  676 +
  677 + /// Returns the greatest integer double value no greater than `this`.
  678 + ///
  679 + /// If this is already an integer valued double, including `-0.0`, or it is
  680 + /// not a finite value, the value is returned unmodified.
  681 + ///
  682 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  683 + /// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
  684 + double floorToDouble() => value.floorToDouble();
  685 +
  686 + /// Returns the least integer double value no smaller than `this`.
  687 + ///
  688 + /// If this is already an integer valued double, including `-0.0`, or it is
  689 + /// not a finite value, the value is returned unmodified.
  690 + ///
  691 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  692 + /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
  693 + double ceilToDouble() => value.ceilToDouble();
  694 +
  695 + /// Returns the integer double value obtained by discarding any fractional
  696 + /// digits from `this`.
  697 + ///
  698 + /// If this is already an integer valued double, including `-0.0`, or it is
  699 + /// not a finite value, the value is returned unmodified.
  700 + ///
  701 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  702 + /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
  703 + /// in the range `0.0 < d < 1.0` it will return 0.0.
  704 + double truncateToDouble() => value.truncateToDouble();
  705 +}
  706 +
  707 +extension RxnDoubleExt on Rx<double?> {
  708 + /// Addition operator.
  709 + Rx<double?>? operator +(num other) {
  710 + if (value != null) {
  711 + value = value! + other;
  712 + return this;
  713 + }
  714 + }
  715 +
  716 + /// Subtraction operator.
  717 + Rx<double?>? operator -(num other) {
  718 + if (value != null) {
  719 + value = value! + other;
  720 + return this;
  721 + }
  722 + }
  723 +
  724 + /// Multiplication operator.
  725 + double? operator *(num other) {
  726 + if (value != null) {
  727 + return value! * other;
  728 + }
  729 + }
  730 +
  731 + double? operator %(num other) {
  732 + if (value != null) {
  733 + return value! % other;
  734 + }
  735 + }
  736 +
  737 + /// Division operator.
  738 + double? operator /(num other) {
  739 + if (value != null) {
  740 + return value! / other;
  741 + }
  742 + }
  743 +
  744 + /// Truncating division operator.
  745 + ///
  746 + /// The result of the truncating division `a ~/ b` is equivalent to
  747 + /// `(a / b).truncate()`.
  748 + int? operator ~/(num other) {
  749 + if (value != null) {
  750 + return value! ~/ other;
  751 + }
  752 + }
  753 +
  754 + /// Negate operator. */
  755 + double? operator -() {
  756 + if (value != null) {
  757 + return -value!;
  758 + }
  759 + }
  760 +
  761 + /// Returns the absolute value of this [double].
  762 + double? abs() {
  763 + return value?.abs();
  764 + }
  765 +
  766 + /// Returns the sign of the double's numerical value.
  767 + ///
  768 + /// Returns -1.0 if the value is less than zero,
  769 + /// +1.0 if the value is greater than zero,
  770 + /// and the value itself if it is -0.0, 0.0 or NaN.
  771 + double? get sign => value?.sign;
  772 +
  773 + /// Returns the integer closest to `this`.
  774 + ///
  775 + /// Rounds away from zero when there is no closest integer:
  776 + /// `(3.5).round() == 4` and `(-3.5).round() == -4`.
  777 + ///
  778 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  779 + int? round() => value?.round();
  780 +
  781 + /// Returns the greatest integer no greater than `this`.
  782 + ///
  783 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  784 + int? floor() => value?.floor();
  785 +
  786 + /// Returns the least integer no smaller than `this`.
  787 + ///
  788 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  789 + int? ceil() => value?.ceil();
  790 +
  791 + /// Returns the integer obtained by discarding any fractional
  792 + /// digits from `this`.
  793 + ///
  794 + /// If `this` is not finite (`NaN` or infinity), throws an [UnsupportedError].
  795 + int? truncate() => value?.truncate();
  796 +
  797 + /// Returns the integer double value closest to `this`.
  798 + ///
  799 + /// Rounds away from zero when there is no closest integer:
  800 + /// `(3.5).roundToDouble() == 4` and `(-3.5).roundToDouble() == -4`.
  801 + ///
  802 + /// If this is already an integer valued double, including `-0.0`, or it is
  803 + /// not a finite value, the value is returned unmodified.
  804 + ///
  805 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`,
  806 + /// and `-0.0` is therefore considered closer to negative numbers than `0.0`.
  807 + /// This means that for a value, `d` in the range `-0.5 < d < 0.0`,
  808 + /// the result is `-0.0`.
  809 + double? roundToDouble() => value?.roundToDouble();
  810 +
  811 + /// Returns the greatest integer double value no greater than `this`.
  812 + ///
  813 + /// If this is already an integer valued double, including `-0.0`, or it is
  814 + /// not a finite value, the value is returned unmodified.
  815 + ///
  816 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  817 + /// A number `d` in the range `0.0 < d < 1.0` will return `0.0`.
  818 + double? floorToDouble() => value?.floorToDouble();
  819 +
  820 + /// Returns the least integer double value no smaller than `this`.
  821 + ///
  822 + /// If this is already an integer valued double, including `-0.0`, or it is
  823 + /// not a finite value, the value is returned unmodified.
  824 + ///
  825 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  826 + /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`.
  827 + double? ceilToDouble() => value?.ceilToDouble();
  828 +
  829 + /// Returns the integer double value obtained by discarding any fractional
  830 + /// digits from `this`.
  831 + ///
  832 + /// If this is already an integer valued double, including `-0.0`, or it is
  833 + /// not a finite value, the value is returned unmodified.
  834 + ///
  835 + /// For the purpose of rounding, `-0.0` is considered to be below `0.0`.
  836 + /// A number `d` in the range `-1.0 < d < 0.0` will return `-0.0`, and
  837 + /// in the range `0.0 < d < 1.0` it will return 0.0.
  838 + double? truncateToDouble() => value?.truncateToDouble();
  839 +}
  840 +
  841 +class RxDouble extends Rx<double> {
  842 + RxDouble(double initial) : super(initial);
  843 +}
  844 +
  845 +class RxnDouble extends Rx<double?> {
  846 + RxnDouble([double? initial]) : super(initial);
  847 +}
  848 +
  849 +class RxInt extends Rx<int> {
  850 + RxInt(int initial) : super(initial);
  851 +}
  852 +
  853 +class RxnInt extends Rx<int?> {
  854 + RxnInt([int? initial]) : super(initial);
  855 +}
  856 +
  857 +extension RxIntExt on Rx<int> {
  858 + /// Addition operator.
  859 + Rx<int> operator +(int other) {
  860 + value = value + other;
  861 + return this;
  862 + }
  863 +
  864 + /// Subtraction operator.
  865 + Rx<int> operator -(int other) {
  866 + value = value - other;
  867 + return this;
  868 + }
  869 +
  870 + /// Bit-wise and operator.
  871 + ///
  872 + /// Treating both `this` and [other] as sufficiently large two's component
  873 + /// integers, the result is a number with only the bits set that are set in
  874 + /// both `this` and [other]
  875 + ///
  876 + /// If both operands are negative, the result is negative, otherwise
  877 + /// the result is non-negative.
  878 + int operator &(int other) => value & other;
  879 +
  880 + /// Bit-wise or operator.
  881 + ///
  882 + /// Treating both `this` and [other] as sufficiently large two's component
  883 + /// integers, the result is a number with the bits set that are set in either
  884 + /// of `this` and [other]
  885 + ///
  886 + /// If both operands are non-negative, the result is non-negative,
  887 + /// otherwise the result is negative.
  888 + int operator |(int other) => value | other;
  889 +
  890 + /// Bit-wise exclusive-or operator.
  891 + ///
  892 + /// Treating both `this` and [other] as sufficiently large two's component
  893 + /// integers, the result is a number with the bits set that are set in one,
  894 + /// but not both, of `this` and [other]
  895 + ///
  896 + /// If the operands have the same sign, the result is non-negative,
  897 + /// otherwise the result is negative.
  898 + int operator ^(int other) => value ^ other;
  899 +
  900 + /// The bit-wise negate operator.
  901 + ///
  902 + /// Treating `this` as a sufficiently large two's component integer,
  903 + /// the result is a number with the opposite bits set.
  904 + ///
  905 + /// This maps any integer `x` to `-x - 1`.
  906 + int operator ~() => ~value;
  907 +
  908 + /// Shift the bits of this integer to the left by [shiftAmount].
  909 + ///
  910 + /// Shifting to the left makes the number larger, effectively multiplying
  911 + /// the number by `pow(2, shiftIndex)`.
  912 + ///
  913 + /// There is no limit on the size of the result. It may be relevant to
  914 + /// limit intermediate values by using the "and" operator with a suitable
  915 + /// mask.
  916 + ///
  917 + /// It is an error if [shiftAmount] is negative.
  918 + int operator <<(int shiftAmount) => value << shiftAmount;
  919 +
  920 + /// Shift the bits of this integer to the right by [shiftAmount].
  921 + ///
  922 + /// Shifting to the right makes the number smaller and drops the least
  923 + /// significant bits, effectively doing an integer division by
  924 + ///`pow(2, shiftIndex)`.
  925 + ///
  926 + /// It is an error if [shiftAmount] is negative.
  927 + int operator >>(int shiftAmount) => value >> shiftAmount;
  928 +
  929 + /// Returns this integer to the power of [exponent] modulo [modulus].
  930 + ///
  931 + /// The [exponent] must be non-negative and [modulus] must be
  932 + /// positive.
  933 + int modPow(int exponent, int modulus) => value.modPow(exponent, modulus);
  934 +
  935 + /// Returns the modular multiplicative inverse of this integer
  936 + /// modulo [modulus].
  937 + ///
  938 + /// The [modulus] must be positive.
  939 + ///
  940 + /// It is an error if no modular inverse exists.
  941 + int modInverse(int modulus) => value.modInverse(modulus);
498 942
499 /// Returns the greatest common divisor of this integer and [other]. 943 /// Returns the greatest common divisor of this integer and [other].
500 /// 944 ///
@@ -593,51 +1037,293 @@ class RxInt extends _BaseRxNum<int> { @@ -593,51 +1037,293 @@ class RxInt extends _BaseRxNum<int> {
593 /// 1037 ///
594 /// The result of negating an integer always has the opposite sign, except 1038 /// The result of negating an integer always has the opposite sign, except
595 /// for zero, which is its own negation. 1039 /// for zero, which is its own negation.
596 - @override  
597 int operator -() => -value; 1040 int operator -() => -value;
598 1041
599 /// Returns the absolute value of this integer. 1042 /// Returns the absolute value of this integer.
600 /// 1043 ///
601 /// For any integer `x`, the result is the same as `x < 0 ? -x : x`. 1044 /// For any integer `x`, the result is the same as `x < 0 ? -x : x`.
602 - @override  
603 int abs() => value.abs(); 1045 int abs() => value.abs();
604 1046
605 /// Returns the sign of this integer. 1047 /// Returns the sign of this integer.
606 /// 1048 ///
607 /// Returns 0 for zero, -1 for values less than zero and 1049 /// Returns 0 for zero, -1 for values less than zero and
608 /// +1 for values greater than zero. 1050 /// +1 for values greater than zero.
609 - @override  
610 int get sign => value.sign; 1051 int get sign => value.sign;
611 1052
612 /// Returns `this`. 1053 /// Returns `this`.
613 - @override  
614 int round() => value.round(); 1054 int round() => value.round();
615 1055
616 /// Returns `this`. 1056 /// Returns `this`.
617 - @override  
618 int floor() => value.floor(); 1057 int floor() => value.floor();
619 1058
620 /// Returns `this`. 1059 /// Returns `this`.
621 - @override  
622 int ceil() => value.ceil(); 1060 int ceil() => value.ceil();
623 1061
624 /// Returns `this`. 1062 /// Returns `this`.
625 - @override  
626 int truncate() => value.truncate(); 1063 int truncate() => value.truncate();
627 1064
628 /// Returns `this.toDouble()`. 1065 /// Returns `this.toDouble()`.
629 - @override  
630 double roundToDouble() => value.roundToDouble(); 1066 double roundToDouble() => value.roundToDouble();
631 1067
632 /// Returns `this.toDouble()`. 1068 /// Returns `this.toDouble()`.
633 - @override  
634 double floorToDouble() => value.floorToDouble(); 1069 double floorToDouble() => value.floorToDouble();
635 1070
636 /// Returns `this.toDouble()`. 1071 /// Returns `this.toDouble()`.
637 - @override  
638 double ceilToDouble() => value.ceilToDouble(); 1072 double ceilToDouble() => value.ceilToDouble();
639 1073
640 /// Returns `this.toDouble()`. 1074 /// Returns `this.toDouble()`.
641 - @override  
642 double truncateToDouble() => value.truncateToDouble(); 1075 double truncateToDouble() => value.truncateToDouble();
643 } 1076 }
  1077 +
  1078 +extension RxnIntExt on Rx<int?> {
  1079 + /// Addition operator.
  1080 + Rx<int?>? operator +(int other) {
  1081 + if (value != null) {
  1082 + value = value! + other;
  1083 + return this;
  1084 + }
  1085 + }
  1086 +
  1087 + /// Subtraction operator.
  1088 + Rx<int?>? operator -(int other) {
  1089 + if (value != null) {
  1090 + value = value! - other;
  1091 + return this;
  1092 + }
  1093 + }
  1094 +
  1095 + /// Bit-wise and operator.
  1096 + ///
  1097 + /// Treating both `this` and [other] as sufficiently large two's component
  1098 + /// integers, the result is a number with only the bits set that are set in
  1099 + /// both `this` and [other]
  1100 + ///
  1101 + /// If both operands are negative, the result is negative, otherwise
  1102 + /// the result is non-negative.
  1103 + int? operator &(int other) {
  1104 + if (value != null) {
  1105 + return value! & other;
  1106 + }
  1107 + }
  1108 +
  1109 + /// Bit-wise or operator.
  1110 + ///
  1111 + /// Treating both `this` and [other] as sufficiently large two's component
  1112 + /// integers, the result is a number with the bits set that are set in either
  1113 + /// of `this` and [other]
  1114 + ///
  1115 + /// If both operands are non-negative, the result is non-negative,
  1116 + /// otherwise the result is negative.
  1117 + int? operator |(int other) {
  1118 + if (value != null) {
  1119 + return value! | other;
  1120 + }
  1121 + }
  1122 +
  1123 + /// Bit-wise exclusive-or operator.
  1124 + ///
  1125 + /// Treating both `this` and [other] as sufficiently large two's component
  1126 + /// integers, the result is a number with the bits set that are set in one,
  1127 + /// but not both, of `this` and [other]
  1128 + ///
  1129 + /// If the operands have the same sign, the result is non-negative,
  1130 + /// otherwise the result is negative.
  1131 + int? operator ^(int other) {
  1132 + if (value != null) {
  1133 + return value! ^ other;
  1134 + }
  1135 + }
  1136 +
  1137 + /// The bit-wise negate operator.
  1138 + ///
  1139 + /// Treating `this` as a sufficiently large two's component integer,
  1140 + /// the result is a number with the opposite bits set.
  1141 + ///
  1142 + /// This maps any integer `x` to `-x - 1`.
  1143 + int? operator ~() {
  1144 + if (value != null) {
  1145 + return ~value!;
  1146 + }
  1147 + }
  1148 +
  1149 + /// Shift the bits of this integer to the left by [shiftAmount].
  1150 + ///
  1151 + /// Shifting to the left makes the number larger, effectively multiplying
  1152 + /// the number by `pow(2, shiftIndex)`.
  1153 + ///
  1154 + /// There is no limit on the size of the result. It may be relevant to
  1155 + /// limit intermediate values by using the "and" operator with a suitable
  1156 + /// mask.
  1157 + ///
  1158 + /// It is an error if [shiftAmount] is negative.
  1159 + int? operator <<(int shiftAmount) {
  1160 + if (value != null) {
  1161 + return value! << shiftAmount;
  1162 + }
  1163 + }
  1164 +
  1165 + /// Shift the bits of this integer to the right by [shiftAmount].
  1166 + ///
  1167 + /// Shifting to the right makes the number smaller and drops the least
  1168 + /// significant bits, effectively doing an integer division by
  1169 + ///`pow(2, shiftIndex)`.
  1170 + ///
  1171 + /// It is an error if [shiftAmount] is negative.
  1172 + int? operator >>(int shiftAmount) {
  1173 + if (value != null) {
  1174 + return value! >> shiftAmount;
  1175 + }
  1176 + }
  1177 +
  1178 + /// Returns this integer to the power of [exponent] modulo [modulus].
  1179 + ///
  1180 + /// The [exponent] must be non-negative and [modulus] must be
  1181 + /// positive.
  1182 + int? modPow(int exponent, int modulus) => value?.modPow(exponent, modulus);
  1183 +
  1184 + /// Returns the modular multiplicative inverse of this integer
  1185 + /// modulo [modulus].
  1186 + ///
  1187 + /// The [modulus] must be positive.
  1188 + ///
  1189 + /// It is an error if no modular inverse exists.
  1190 + int? modInverse(int modulus) => value?.modInverse(modulus);
  1191 +
  1192 + /// Returns the greatest common divisor of this integer and [other].
  1193 + ///
  1194 + /// If either number is non-zero, the result is the numerically greatest
  1195 + /// integer dividing both `this` and `other`.
  1196 + ///
  1197 + /// The greatest common divisor is independent of the order,
  1198 + /// so `x.gcd(y)` is always the same as `y.gcd(x)`.
  1199 + ///
  1200 + /// For any integer `x`, `x.gcd(x)` is `x.abs()`.
  1201 + ///
  1202 + /// If both `this` and `other` is zero, the result is also zero.
  1203 + int? gcd(int other) => value?.gcd(other);
  1204 +
  1205 + /// Returns true if and only if this integer is even.
  1206 + bool? get isEven => value?.isEven;
  1207 +
  1208 + /// Returns true if and only if this integer is odd.
  1209 + bool? get isOdd => value?.isOdd;
  1210 +
  1211 + /// Returns the minimum number of bits required to store this integer.
  1212 + ///
  1213 + /// The number of bits excludes the sign bit, which gives the natural length
  1214 + /// for non-negative (unsigned) values. Negative values are complemented to
  1215 + /// return the bit position of the first bit that differs from the sign bit.
  1216 + ///
  1217 + /// To find the number of bits needed to store the value as a signed value,
  1218 + /// add one, i.e. use `x.bitLength + 1`.
  1219 + /// ```
  1220 + /// x.bitLength == (-x-1).bitLength
  1221 + ///
  1222 + /// 3.bitLength == 2; // 00000011
  1223 + /// 2.bitLength == 2; // 00000010
  1224 + /// 1.bitLength == 1; // 00000001
  1225 + /// 0.bitLength == 0; // 00000000
  1226 + /// (-1).bitLength == 0; // 11111111
  1227 + /// (-2).bitLength == 1; // 11111110
  1228 + /// (-3).bitLength == 2; // 11111101
  1229 + /// (-4).bitLength == 2; // 11111100
  1230 + /// ```
  1231 + int? get bitLength => value?.bitLength;
  1232 +
  1233 + /// Returns the least significant [width] bits of this integer as a
  1234 + /// non-negative number (i.e. unsigned representation). The returned value
  1235 + /// has zeros in all bit positions higher than [width].
  1236 + /// ```
  1237 + /// (-1).toUnsigned(5) == 31 // 11111111 -> 00011111
  1238 + /// ```
  1239 + /// This operation can be used to simulate arithmetic from low level
  1240 + /// languages.
  1241 + /// For example, to increment an 8 bit quantity:
  1242 + /// ```
  1243 + /// q = (q + 1).toUnsigned(8);
  1244 + /// ```
  1245 + /// `q` will count from `0` up to `255` and then wrap around to `0`.
  1246 + ///
  1247 + /// If the input fits in [width] bits without truncation, the result is the
  1248 + /// same as the input. The minimum width needed to avoid truncation of `x` is
  1249 + /// given by `x.bitLength`, i.e.
  1250 + /// ```
  1251 + /// x == x.toUnsigned(x.bitLength);
  1252 + /// ```
  1253 + int? toUnsigned(int width) => value?.toUnsigned(width);
  1254 +
  1255 + /// Returns the least significant [width] bits of this integer, extending the
  1256 + /// highest retained bit to the sign. This is the same as truncating the
  1257 + /// value to fit in [width] bits using an signed 2-s complement
  1258 + /// representation.
  1259 + /// The returned value has the same bit value in all positions higher than
  1260 + /// [width].
  1261 + ///
  1262 + /// ```
  1263 + /// V--sign bit-V
  1264 + /// 16.toSigned(5) == -16 // 00010000 -> 11110000
  1265 + /// 239.toSigned(5) == 15 // 11101111 -> 00001111
  1266 + /// ^ ^
  1267 + /// ```
  1268 + /// This operation can be used to simulate arithmetic from low level
  1269 + /// languages.
  1270 + /// For example, to increment an 8 bit signed quantity:
  1271 + /// ```
  1272 + /// q = (q + 1).toSigned(8);
  1273 + /// ```
  1274 + /// `q` will count from `0` up to `127`, wrap to `-128` and count back up to
  1275 + /// `127`.
  1276 + ///
  1277 + /// If the input value fits in [width] bits without truncation, the result is
  1278 + /// the same as the input. The minimum width needed to avoid truncation
  1279 + /// of `x` is `x.bitLength + 1`, i.e.
  1280 + /// ```
  1281 + /// x == x.toSigned(x.bitLength + 1);
  1282 + /// ```
  1283 + int? toSigned(int width) => value?.toSigned(width);
  1284 +
  1285 + /// Return the negative value of this integer.
  1286 + ///
  1287 + /// The result of negating an integer always has the opposite sign, except
  1288 + /// for zero, which is its own negation.
  1289 + int? operator -() {
  1290 + if (value != null) {
  1291 + return -value!;
  1292 + }
  1293 + }
  1294 +
  1295 + /// Returns the absolute value of this integer.
  1296 + ///
  1297 + /// For any integer `x`, the result is the same as `x < 0 ? -x : x`.
  1298 + int? abs() => value?.abs();
  1299 +
  1300 + /// Returns the sign of this integer.
  1301 + ///
  1302 + /// Returns 0 for zero, -1 for values less than zero and
  1303 + /// +1 for values greater than zero.
  1304 + int? get sign => value?.sign;
  1305 +
  1306 + /// Returns `this`.
  1307 + int? round() => value?.round();
  1308 +
  1309 + /// Returns `this`.
  1310 + int? floor() => value?.floor();
  1311 +
  1312 + /// Returns `this`.
  1313 + int? ceil() => value?.ceil();
  1314 +
  1315 + /// Returns `this`.
  1316 + int? truncate() => value?.truncate();
  1317 +
  1318 + /// Returns `this.toDouble()`.
  1319 + double? roundToDouble() => value?.roundToDouble();
  1320 +
  1321 + /// Returns `this.toDouble()`.
  1322 + double? floorToDouble() => value?.floorToDouble();
  1323 +
  1324 + /// Returns `this.toDouble()`.
  1325 + double? ceilToDouble() => value?.ceilToDouble();
  1326 +
  1327 + /// Returns `this.toDouble()`.
  1328 + double? truncateToDouble() => value?.truncateToDouble();
  1329 +}
  1 +part of rx_types;
  2 +
  3 +extension RxStringExt on Rx<String> {
  4 + String operator +(String val) => _value + val;
  5 +
  6 + int compareTo(String other) {
  7 + return value.compareTo(other);
  8 + }
  9 +
  10 + /// Returns true if this string ends with [other]. For example:
  11 + ///
  12 + /// 'Dart'.endsWith('t'); // true
  13 + bool endsWith(String other) {
  14 + return value.endsWith(other);
  15 + }
  16 +
  17 + /// Returns true if this string starts with a match of [pattern].
  18 + bool startsWith(Pattern pattern, [int index = 0]) {
  19 + return value.startsWith(pattern, index);
  20 + }
  21 +
  22 + /// Returns the position of the first match of [pattern] in this string
  23 + int indexOf(Pattern pattern, [int start = 0]) {
  24 + return value.indexOf(pattern, start);
  25 + }
  26 +
  27 + /// Returns the starting position of the last match [pattern] in this string,
  28 + /// searching backward starting at [start], inclusive:
  29 + int lastIndexOf(Pattern pattern, [int? start]) {
  30 + return value.lastIndexOf(pattern, start);
  31 + }
  32 +
  33 + /// Returns true if this string is empty.
  34 + bool get isEmpty => value.isEmpty;
  35 +
  36 + /// Returns true if this string is not empty.
  37 + bool get isNotEmpty => !isEmpty;
  38 +
  39 + /// Returns the substring of this string that extends from [startIndex],
  40 + /// inclusive, to [endIndex], exclusive
  41 + String substring(int startIndex, [int? endIndex]) {
  42 + return value.substring(startIndex, endIndex);
  43 + }
  44 +
  45 + /// Returns the string without any leading and trailing whitespace.
  46 + String trim() {
  47 + return value.trim();
  48 + }
  49 +
  50 + /// Returns the string without any leading whitespace.
  51 + ///
  52 + /// As [trim], but only removes leading whitespace.
  53 + String trimLeft() {
  54 + return value.trimLeft();
  55 + }
  56 +
  57 + /// Returns the string without any trailing whitespace.
  58 + ///
  59 + /// As [trim], but only removes trailing whitespace.
  60 + String trimRight() {
  61 + return value.trimRight();
  62 + }
  63 +
  64 + /// Pads this string on the left if it is shorter than [width].
  65 + ///
  66 + /// Return a new string that prepends [padding] onto this string
  67 + /// one time for each position the length is less than [width].
  68 + String padLeft(int width, [String padding = ' ']) {
  69 + return value.padLeft(width, padding);
  70 + }
  71 +
  72 + /// Pads this string on the right if it is shorter than [width].
  73 +
  74 + /// Return a new string that appends [padding] after this string
  75 + /// one time for each position the length is less than [width].
  76 + String padRight(int width, [String padding = ' ']) {
  77 + return value.padRight(width, padding);
  78 + }
  79 +
  80 + /// Returns true if this string contains a match of [other]:
  81 + bool contains(Pattern other, [int startIndex = 0]) {
  82 + return value.contains(other, startIndex);
  83 + }
  84 +
  85 + /// Replaces all substrings that match [from] with [replace].
  86 + String replaceAll(Pattern from, String replace) {
  87 + return value.replaceAll(from, replace);
  88 + }
  89 +
  90 + /// Splits the string at matches of [pattern] and returns a list
  91 + /// of substrings.
  92 + List<String> split(Pattern pattern) {
  93 + return value.split(pattern);
  94 + }
  95 +
  96 + /// Returns an unmodifiable list of the UTF-16 code units of this string.
  97 + List<int> get codeUnits => value.codeUnits;
  98 +
  99 + /// Returns an [Iterable] of Unicode code-points of this string.
  100 + ///
  101 + /// If the string contains surrogate pairs, they are combined and returned
  102 + /// as one integer by this iterator. Unmatched surrogate halves are treated
  103 + /// like valid 16-bit code-units.
  104 + Runes get runes => value.runes;
  105 +
  106 + /// Converts all characters in this string to lower case.
  107 + /// If the string is already in all lower case, this method returns `this`.
  108 + String toLowerCase() {
  109 + return value.toLowerCase();
  110 + }
  111 +
  112 + /// Converts all characters in this string to upper case.
  113 + /// If the string is already in all upper case, this method returns `this`.
  114 + String toUpperCase() {
  115 + return value.toUpperCase();
  116 + }
  117 +
  118 + Iterable<Match> allMatches(String string, [int start = 0]) {
  119 + return value.allMatches(string, start);
  120 + }
  121 +
  122 + Match? matchAsPrefix(String string, [int start = 0]) {
  123 + return value.matchAsPrefix(string, start);
  124 + }
  125 +}
  126 +
  127 +extension RxnStringExt on Rx<String?> {
  128 + String operator +(String val) => (_value ?? '') + val;
  129 +
  130 + int? compareTo(String other) {
  131 + return value?.compareTo(other);
  132 + }
  133 +
  134 + /// Returns true if this string ends with [other]. For example:
  135 + ///
  136 + /// 'Dart'.endsWith('t'); // true
  137 + bool? endsWith(String other) {
  138 + return value?.endsWith(other);
  139 + }
  140 +
  141 + /// Returns true if this string starts with a match of [pattern].
  142 + bool? startsWith(Pattern pattern, [int index = 0]) {
  143 + return value?.startsWith(pattern, index);
  144 + }
  145 +
  146 + /// Returns the position of the first match of [pattern] in this string
  147 + int? indexOf(Pattern pattern, [int start = 0]) {
  148 + return value?.indexOf(pattern, start);
  149 + }
  150 +
  151 + /// Returns the starting position of the last match [pattern] in this string,
  152 + /// searching backward starting at [start], inclusive:
  153 + int? lastIndexOf(Pattern pattern, [int? start]) {
  154 + return value?.lastIndexOf(pattern, start);
  155 + }
  156 +
  157 + /// Returns true if this string is empty.
  158 + bool? get isEmpty => value?.isEmpty;
  159 +
  160 + /// Returns true if this string is not empty.
  161 + bool? get isNotEmpty => value?.isNotEmpty;
  162 +
  163 + /// Returns the substring of this string that extends from [startIndex],
  164 + /// inclusive, to [endIndex], exclusive
  165 + String? substring(int startIndex, [int? endIndex]) {
  166 + return value?.substring(startIndex, endIndex);
  167 + }
  168 +
  169 + /// Returns the string without any leading and trailing whitespace.
  170 + String? trim() {
  171 + return value?.trim();
  172 + }
  173 +
  174 + /// Returns the string without any leading whitespace.
  175 + ///
  176 + /// As [trim], but only removes leading whitespace.
  177 + String? trimLeft() {
  178 + return value?.trimLeft();
  179 + }
  180 +
  181 + /// Returns the string without any trailing whitespace.
  182 + ///
  183 + /// As [trim], but only removes trailing whitespace.
  184 + String? trimRight() {
  185 + return value?.trimRight();
  186 + }
  187 +
  188 + /// Pads this string on the left if it is shorter than [width].
  189 + ///
  190 + /// Return a new string that prepends [padding] onto this string
  191 + /// one time for each position the length is less than [width].
  192 + String? padLeft(int width, [String padding = ' ']) {
  193 + return value?.padLeft(width, padding);
  194 + }
  195 +
  196 + /// Pads this string on the right if it is shorter than [width].
  197 +
  198 + /// Return a new string that appends [padding] after this string
  199 + /// one time for each position the length is less than [width].
  200 + String? padRight(int width, [String padding = ' ']) {
  201 + return value?.padRight(width, padding);
  202 + }
  203 +
  204 + /// Returns true if this string contains a match of [other]:
  205 + bool? contains(Pattern other, [int startIndex = 0]) {
  206 + return value?.contains(other, startIndex);
  207 + }
  208 +
  209 + /// Replaces all substrings that match [from] with [replace].
  210 + String? replaceAll(Pattern from, String replace) {
  211 + return value?.replaceAll(from, replace);
  212 + }
  213 +
  214 + /// Splits the string at matches of [pattern] and returns a list
  215 + /// of substrings.
  216 + List<String>? split(Pattern pattern) {
  217 + return value?.split(pattern);
  218 + }
  219 +
  220 + /// Returns an unmodifiable list of the UTF-16 code units of this string.
  221 + List<int>? get codeUnits => value?.codeUnits;
  222 +
  223 + /// Returns an [Iterable] of Unicode code-points of this string.
  224 + ///
  225 + /// If the string contains surrogate pairs, they are combined and returned
  226 + /// as one integer by this iterator. Unmatched surrogate halves are treated
  227 + /// like valid 16-bit code-units.
  228 + Runes? get runes => value?.runes;
  229 +
  230 + /// Converts all characters in this string to lower case.
  231 + /// If the string is already in all lower case, this method returns `this`.
  232 + String? toLowerCase() {
  233 + return value?.toLowerCase();
  234 + }
  235 +
  236 + /// Converts all characters in this string to upper case.
  237 + /// If the string is already in all upper case, this method returns `this`.
  238 + String? toUpperCase() {
  239 + return value?.toUpperCase();
  240 + }
  241 +
  242 + Iterable<Match>? allMatches(String string, [int start = 0]) {
  243 + return value?.allMatches(string, start);
  244 + }
  245 +
  246 + Match? matchAsPrefix(String string, [int start = 0]) {
  247 + return value?.matchAsPrefix(string, start);
  248 + }
  249 +}
  250 +
  251 +/// Rx class for `String` Type.
  252 +class RxString extends Rx<String> implements Comparable<String>, Pattern {
  253 + RxString(String initial) : super(initial);
  254 +
  255 + @override
  256 + Iterable<Match> allMatches(String string, [int start = 0]) {
  257 + return value.allMatches(string, start);
  258 + }
  259 +
  260 + @override
  261 + Match? matchAsPrefix(String string, [int start = 0]) {
  262 + return value.matchAsPrefix(string, start);
  263 + }
  264 +
  265 + @override
  266 + int compareTo(String other) {
  267 + return value.compareTo(other);
  268 + }
  269 +}
  270 +
  271 +/// Rx class for `String` Type.
  272 +class RxnString extends Rx<String?> implements Comparable<String>, Pattern {
  273 + RxnString(String? initial) : super(initial);
  274 +
  275 + @override
  276 + Iterable<Match> allMatches(String string, [int start = 0]) {
  277 + return value!.allMatches(string, start);
  278 + }
  279 +
  280 + @override
  281 + Match? matchAsPrefix(String string, [int start = 0]) {
  282 + return value!.matchAsPrefix(string, start);
  283 + }
  284 +
  285 + @override
  286 + int compareTo(String other) {
  287 + return value!.compareTo(other);
  288 + }
  289 +}
@@ -10,6 +10,7 @@ import '../rx_typedefs/rx_typedefs.dart'; @@ -10,6 +10,7 @@ import '../rx_typedefs/rx_typedefs.dart';
10 part 'rx_core/rx_impl.dart'; 10 part 'rx_core/rx_impl.dart';
11 part 'rx_core/rx_interface.dart'; 11 part 'rx_core/rx_interface.dart';
12 part 'rx_core/rx_num.dart'; 12 part 'rx_core/rx_num.dart';
  13 +part 'rx_core/rx_string.dart';
13 14
14 part 'rx_iterables/rx_list.dart'; 15 part 'rx_iterables/rx_list.dart';
15 part 'rx_iterables/rx_set.dart'; 16 part 'rx_iterables/rx_set.dart';
@@ -104,24 +104,3 @@ class ObxValue<T extends RxInterface> extends ObxWidget { @@ -104,24 +104,3 @@ class ObxValue<T extends RxInterface> extends ObxWidget {
104 @override 104 @override
105 Widget build() => builder(data); 105 Widget build() => builder(data);
106 } 106 }
107 -  
108 -/// Similar to Obx, but manages a local state.  
109 -/// Pass the initial data in constructor.  
110 -/// Useful for simple local states, like toggles, visibility, themes,  
111 -/// button states, etc.  
112 -/// Sample:  
113 -/// ObxValue((data) => Switch(  
114 -/// value: data.value,  
115 -/// onChanged: (flag) => data.value = flag,  
116 -/// ),  
117 -/// false.obs,  
118 -/// ),  
119 -class RxValue<T> extends ObxWidget {  
120 - final Widget Function(T? data) builder;  
121 - final Rx<T> data = Rx<T>();  
122 -  
123 - RxValue(this.builder, {Key? key}) : super(key: key);  
124 -  
125 - @override  
126 - Widget build() => builder(data.value);  
127 -}  
1 name: get 1 name: get
2 description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX. 2 description: Open screens/snackbars/dialogs without context, manage states and inject dependencies easily with GetX.
3 -version: 4.0.0-nullsafety.2 3 +version: 4.0.0
4 homepage: https://github.com/jonataslaw/getx 4 homepage: https://github.com/jonataslaw/getx
5 5
6 environment: 6 environment:
@@ -129,4 +129,36 @@ void main() { @@ -129,4 +129,36 @@ void main() {
129 await Future.delayed(Duration(milliseconds: 100)); 129 await Future.delayed(Duration(milliseconds: 100));
130 expect(3, timesCalled); 130 expect(3, timesCalled);
131 }); 131 });
  132 +
  133 + test('Rx String with non null values', () async {
  134 + final reactiveString = Rx<String>("abc");
  135 + var currentString;
  136 + reactiveString.listen((newString) {
  137 + currentString = newString;
  138 + });
  139 +
  140 + expect(reactiveString.endsWith("c"), true);
  141 +
  142 + // we call 3
  143 + reactiveString("b");
  144 +
  145 + await Future.delayed(Duration.zero);
  146 + expect(currentString, "b");
  147 + });
  148 +
  149 + test('Rx String with null values', () async {
  150 + var reactiveString = Rx<String?>(null);
  151 + var currentString;
  152 +
  153 + reactiveString.listen((newString) {
  154 + currentString = newString;
  155 + });
  156 +
  157 + // we call 3
  158 + reactiveString("abc");
  159 +
  160 + await Future.delayed(Duration.zero);
  161 + expect(reactiveString.endsWith("c"), true);
  162 + expect(currentString, "abc");
  163 + });
132 } 164 }