@@ -110,6 +110,30 @@ struct ScalarTraits {
110
110
};
111
111
112
112
113
+ // / This class should be specialized by any type that can be 'null' in JSON.
114
+ // / For example:
115
+ // /
116
+ // / template<>
117
+ // / struct NullableTraits<MyType *> > {
118
+ // / static bool isNull(MyType *&ptr) {
119
+ // / return !ptr;
120
+ // / }
121
+ // / static MyType &get(MyType *&ptr) {
122
+ // / return *ptr;
123
+ // / }
124
+ // / };
125
+ template <typename T>
126
+ struct NullableTraits {
127
+ // Must provide:
128
+ //
129
+ // Function to return true if the value is 'null'.
130
+ // static bool isNull(const T &Val);
131
+ //
132
+ // Function to return a reference to the unwrapped value.
133
+ // static T::value_type &get(const T &Val);
134
+ };
135
+
136
+
113
137
// / This class should be specialized by any type that needs to be converted
114
138
// / to/from a JSON array. For example:
115
139
// /
@@ -249,6 +273,23 @@ template<typename T>
249
273
struct has_ArrayTraits : public std ::integral_constant<bool ,
250
274
has_ArrayMethodTraits<T>::value > { };
251
275
276
+ // Test if NullableTraits<T> is defined on type T.
277
+ template <class T >
278
+ struct has_NullableTraits
279
+ {
280
+ typedef bool (*Signature_isNull)(T&);
281
+
282
+ template <typename U>
283
+ static char test (SameType<Signature_isNull, &U::isNull> *);
284
+
285
+ template <typename U>
286
+ static double test (...);
287
+
288
+ public:
289
+ static bool const value =
290
+ (sizeof (test<NullableTraits<T>>(nullptr )) == 1 );
291
+ };
292
+
252
293
inline bool isNumber (StringRef S) {
253
294
static const char DecChars[] = " 0123456789" ;
254
295
if (S.find_first_not_of (DecChars) == StringRef::npos)
@@ -285,6 +326,7 @@ struct missingTraits : public std::integral_constant<bool,
285
326
!has_ScalarEnumerationTraits<T>::value
286
327
&& !has_ScalarBitSetTraits<T>::value
287
328
&& !has_ScalarTraits<T>::value
329
+ && !has_NullableTraits<T>::value
288
330
&& !has_ObjectTraits<T>::value
289
331
&& !has_ArrayTraits<T>::value> {};
290
332
@@ -338,6 +380,7 @@ class Output {
338
380
void endBitSetScalar ();
339
381
340
382
void scalarString (StringRef &, bool );
383
+ void null ();
341
384
342
385
template <typename T>
343
386
void enumCase (T &Val, const char * Str, const T ConstVal) {
@@ -579,6 +622,16 @@ jsonize(Output &out, T &Val, bool) {
579
622
}
580
623
581
624
625
+ template <typename T>
626
+ typename std::enable_if<has_NullableTraits<T>::value,void >::type
627
+ jsonize (Output &out, T &Obj, bool ) {
628
+ if (NullableTraits<T>::isNull (Obj))
629
+ out.null ();
630
+ else
631
+ jsonize (out, NullableTraits<T>::get (Obj), true );
632
+ }
633
+
634
+
582
635
template <typename T>
583
636
typename std::enable_if<validatedObjectTraits<T>::value, void >::type
584
637
jsonize (Output &out, T &Val, bool ) {
0 commit comments