19
19
20
20
#include < cstdint>
21
21
#include < iosfwd>
22
+ #include < limits>
22
23
#include < string>
23
24
#include < vector>
24
25
26
+ #include " app/meta/type_traits.h"
25
27
#include " firebase/firestore/map_field_value.h"
26
28
27
29
namespace firebase {
@@ -50,6 +52,17 @@ class GeoPoint;
50
52
* foo_value() will fail (and cause a crash).
51
53
*/
52
54
class FieldValue final {
55
+ // Helper aliases for `Increment` member functions.
56
+ // Qualifying `is_integer` is to prevent ambiguity with the
57
+ // `FieldValue::is_integer` member function.
58
+ // Note: normally, `enable_if::type` would be included in the alias, but such
59
+ // a declaration breaks SWIG (presumably, SWIG cannot handle `typename` within
60
+ // an alias template).
61
+ template <typename T>
62
+ using EnableIfIntegral = enable_if<::firebase::is_integer<T>::value, int >;
63
+ template <typename T>
64
+ using EnableIfFloatingPoint = enable_if<is_floating_point<T>::value, int >;
65
+
53
66
public:
54
67
/* *
55
68
* The enumeration of all valid runtime types of FieldValue.
@@ -315,7 +328,8 @@ class FieldValue final {
315
328
#if defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
316
329
/* *
317
330
* Returns a special value that can be used with `Set()` or `Update()` that
318
- * tells the server to increment the field's current value by the given value.
331
+ * tells the server to increment the field's current value by the given
332
+ * integer value.
319
333
*
320
334
* If the current field value is an integer, possible integer overflows are
321
335
* resolved to `LONG_MAX` or `LONG_MIN`. If the current field value is a
@@ -325,16 +339,29 @@ class FieldValue final {
325
339
* If field is not an integer or a double, or if the field does not yet exist,
326
340
* the transformation will set the field to the given value.
327
341
*
328
- * @param by_value The integer value to increment by.
342
+ * @param by_value The integer value to increment by. Should be an integer
343
+ * type not larger than `int64_t`.
329
344
* @return The FieldValue sentinel for use in a call to `Set()` or `Update().`
330
345
*/
331
- static FieldValue IntegerIncrement (int64_t by_value);
346
+ template <typename T, typename EnableIfIntegral<T>::type = 0 >
347
+ static FieldValue Increment (T by_value) {
348
+ // Note: Doxygen will run into trouble if this function's definition is
349
+ // moved outside the class body.
350
+ static_assert (
351
+ std::numeric_limits<T>::max () <= std::numeric_limits<int64_t >::max (),
352
+ " The integer type you provided is larger than can fit in an int64_t. "
353
+ " If you are sure the value will not be truncated, please explicitly "
354
+ " cast to int64_t before passing it to FieldValue::Increment()." );
355
+ return IntegerIncrement (static_cast <int64_t >(by_value));
356
+ }
357
+
332
358
#endif // if defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
333
359
334
360
#if defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
335
361
/* *
336
362
* Returns a special value that can be used with `Set()` or `Update()` that
337
- * tells the server to increment the field's current value by the given value.
363
+ * tells the server to increment the field's current value by the given
364
+ * floating point value.
338
365
*
339
366
* If the current field value is an integer, possible integer overflows are
340
367
* resolved to `LONG_MAX` or `LONG_MIN`. If the current field value is a
@@ -344,10 +371,23 @@ class FieldValue final {
344
371
* If field is not an integer or a double, or if the field does not yet exist,
345
372
* the transformation will set the field to the given value.
346
373
*
347
- * @param by_value The double value to increment by.
374
+ * @param by_value The double value to increment by. Should be a floating
375
+ * point type no larger than `double`.
348
376
* @return The FieldValue sentinel for use in a call to `Set()` or `Update().`
349
377
*/
350
- static FieldValue DoubleIncrement (double by_value);
378
+ template <typename T, typename EnableIfFloatingPoint<T>::type = 0 >
379
+ static FieldValue Increment (T by_value) {
380
+ // Note: Doxygen will run into trouble if this function's definition is
381
+ // moved outside the class body.
382
+ static_assert (
383
+ std::numeric_limits<T>::max () <= std::numeric_limits<double >::max (),
384
+ " The floating point type you provided is larger than can fit in a "
385
+ " double. If you are sure the value will not be truncated, please "
386
+ " explicitly cast to double before passing it to "
387
+ " FieldValue::Increment()." );
388
+ return DoubleIncrement (static_cast <double >(by_value));
389
+ }
390
+
351
391
#endif // if defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
352
392
353
393
/* *
@@ -380,6 +420,9 @@ class FieldValue final {
380
420
381
421
explicit FieldValue (FieldValueInternal* internal);
382
422
423
+ static FieldValue IntegerIncrement (int64_t by_value);
424
+ static FieldValue DoubleIncrement (double by_value);
425
+
383
426
FieldValueInternal* internal_ = nullptr ;
384
427
};
385
428
0 commit comments