summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsd.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2022-11-12 18:59:21 -1000
committerNat Goodspeed <nat@lindenlab.com>2022-11-12 18:59:21 -1000
commit4349cb6165e983ff6bdd45ad1b82bb98bfc0436f (patch)
treeeeb39af41808a4846a16a558118a4b929abe71bb /indra/llcommon/llsd.h
parentcd997f21c272987e954f5890ed14fcc327eb734e (diff)
DRTVWR-575: Address review comments on Xcode 14.1 type tweaks.
Introduce LLSD template constructors and assignment operators to disambiguate construction or assignment from any integer type to Integer, likewise any floating point type to Real. Use new narrow() function to validate conversions. For LLSD method parameters converted from LLSD::Integer to size_t, where the method previously checked for a negative argument, make it now check for size_t converted from negative: in other words, more than S32_MAX. The risk of having a parameter forced from negative to unsigned exceeds the risk of a valid length or index over that max. In lltracerecording.cpp's PeriodicRecording, now that mCurPeriod and mNumRecordedPeriods are size_t instead of S32, defend against subtracting 1 from 0. Use narrow() to validate newly-introduced narrowing conversions. Make llclamp() return the type of the raw input value, even if the types of the boundary values differ. std::ostream::tellp() no longer returns a value we can directly report as a number. Cast to U64.
Diffstat (limited to 'indra/llcommon/llsd.h')
-rw-r--r--indra/llcommon/llsd.h50
1 files changed, 36 insertions, 14 deletions
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index f034470da7..c1406cf73f 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -30,6 +30,7 @@
#include <map>
#include <string>
#include <vector>
+#include <type_traits>
#include "stdtypes.h"
@@ -192,7 +193,17 @@ public:
/** @name Convenience Constructors */
//@{
- LLSD(F32); // F32 -> Real
+ // support construction from size_t et al.
+ template <typename VALUE,
+ typename std::enable_if<std::is_integral<VALUE>::value &&
+ ! std::is_same<VALUE, Boolean>::value,
+ bool>::type = true>
+ LLSD(VALUE v): LLSD(Integer(narrow(v))) {}
+ // support construction from F32 et al.
+ template <typename VALUE,
+ typename std::enable_if<std::is_floating_point<VALUE>::value,
+ bool>::type = true>
+ LLSD(VALUE v): LLSD(Real(narrow(v))) {}
//@}
/** @name Scalar Assignment */
@@ -205,15 +216,21 @@ public:
void assign(const Date&);
void assign(const URI&);
void assign(const Binary&);
-
- LLSD& operator=(Boolean v) { assign(v); return *this; }
- LLSD& operator=(Integer v) { assign(v); return *this; }
- LLSD& operator=(Real v) { assign(v); return *this; }
- LLSD& operator=(const String& v) { assign(v); return *this; }
- LLSD& operator=(const UUID& v) { assign(v); return *this; }
- LLSD& operator=(const Date& v) { assign(v); return *this; }
- LLSD& operator=(const URI& v) { assign(v); return *this; }
- LLSD& operator=(const Binary& v) { assign(v); return *this; }
+
+ // support assignment from size_t et al.
+ template <typename VALUE,
+ typename std::enable_if<std::is_integral<VALUE>::value &&
+ ! std::is_same<VALUE, Boolean>::value,
+ bool>::type = true>
+ void assign(VALUE v) { assign(Integer(narrow(v))); }
+ // support assignment from F32 et al.
+ template <typename VALUE,
+ typename std::enable_if<std::is_floating_point<VALUE>::value,
+ bool>::type = true>
+ void assign(VALUE v) { assign(Real(narrow(v))); }
+
+ template <typename VALUE>
+ LLSD& operator=(VALUE v) { assign(v); return *this; }
//@}
/**
@@ -275,7 +292,6 @@ public:
//@{
LLSD(const char*);
void assign(const char*);
- LLSD& operator=(const char* v) { assign(v); return *this; }
//@}
/** @name Map Values */
@@ -317,9 +333,15 @@ public:
// accept size_t so we can index relative to size()
const LLSD& operator[](size_t) const;
LLSD& operator[](size_t);
- // overload to disambiguate [0], [1] et al.
- const LLSD& operator[](Integer i) const { return (*this)[size_t(i)]; }
- LLSD& operator[](Integer i) { return (*this)[size_t(i)]; }
+ // template overloads to support int literals, U32 et al.
+ template <typename IDX,
+ typename std::enable_if<std::is_convertible<IDX, size_t>::value,
+ bool>::type = true>
+ const LLSD& operator[](IDX i) const { return (*this)[size_t(i)]; }
+ template <typename IDX,
+ typename std::enable_if<std::is_convertible<IDX, size_t>::value,
+ bool>::type = true>
+ LLSD& operator[](IDX i) { return (*this)[size_t(i)]; }
//@}
/** @name Iterators */