BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlat_nullablevaluefunctions.h
Go to the documentation of this file.
1/// @file bdlat_nullablevaluefunctions.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_nullablevaluefunctions.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_NULLABLEVALUEFUNCTIONS
9#define INCLUDED_BDLAT_NULLABLEVALUEFUNCTIONS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_nullablevaluefunctions bdlat_nullablevaluefunctions
15/// @brief Provide a namespace defining nullable value functions.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_nullablevaluefunctions
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_nullablevaluefunctions-purpose"> Purpose</a>
25/// * <a href="#bdlat_nullablevaluefunctions-classes"> Classes </a>
26/// * <a href="#bdlat_nullablevaluefunctions-description"> Description </a>
27/// * <a href="#bdlat_nullablevaluefunctions-usage"> Usage </a>
28/// * <a href="#bdlat_nullablevaluefunctions-example-1-defining-a-nullable-type"> Example 1: Defining a "Nullable" Type </a>
29/// * <a href="#bdlat_nullablevaluefunctions-example-2-using-the-infrastructure-via-general-methods"> Example 2: Using the Infrastructure Via General Methods </a>
30/// * <a href="#bdlat_nullablevaluefunctions-example-3-defining-utility-functions"> Example 3: Defining Utility Functions </a>
31/// * <a href="#bdlat_nullablevaluefunctions-example-4-achieving-type-independence"> Example 4: Achieving Type Independence </a>
32///
33/// # Purpose {#bdlat_nullablevaluefunctions-purpose}
34/// Provide a namespace defining nullable value functions.
35///
36/// # Classes {#bdlat_nullablevaluefunctions-classes}
37///
38/// - bdlat_NullableValueFunctions: namespace for "nullable" value functions
39///
40/// @see bdlb_nullablevalue
41///
42/// # Description {#bdlat_nullablevaluefunctions-description}
43/// The `bdlat_NullableValueFunctions` `namespace` provided in this
44/// component defines parameterized functions that expose "nullable" behavior
45/// for "nullable" types. See the {`bdlat`} package-level documentation for a
46/// full description of "nullable" types.
47///
48/// The functions in this namespace allow users to:
49/// * make the nullable object contain a value (`makeValue`),
50/// * manipulate the value contained in a nullable object using a parameterized
51/// manipulator functor (`manipulateValue`),
52/// * access the value contained in a nullable object using a parameterized
53/// accessor functor (`accessValue`), and
54/// * check whether the nullable object is null or not (`isNull`).
55///
56/// A type becomes part of the `bdlat` "nullable" framework by creating, in the
57/// namespace where the type is defined, specializations of the following four
58/// (free) function templates:
59///
60/// A type becomes part of the `bdlat` "nullable" framework by creating, in the
61/// namespace where the type is defined, overloads of the following two (free)
62/// functions and two (free) function templates. Note that the placeholder
63/// `YOUR_TYPE` is not a template argument and should be replaced with the name
64/// of the type being plugged into the framework.
65/// @code
66/// // MANIPULATORS
67/// void bdlat_nullableValueMakeValue(YOUR_TYPE *object);
68/// // Assign to the specified "nullable" 'object' the default value for
69/// // the contained type (i.e., 'ValueType()').
70///
71/// template <class MANIPULATOR>
72/// int bdlat_nullableValueManipulateValue(YOUR_TYPE *object,
73/// MANIPULATOR& manipulator);
74/// // Invoke the specified 'manipulator' on the address of the value
75/// // stored in the specified "nullable" 'object'. Return the value from
76/// // the invocation of 'manipulator'. The behavior is undefined if
77/// // 'object' contains a null value.
78///
79/// // ACCESSORS
80/// template <class ACCESSOR>
81/// int bdlat_nullableValueAccessValue(const YOUR_TYPE& object,
82/// ACCESSOR& accessor);
83/// // Invoke the specified 'accessor' on a 'const'-reference to the value
84/// // stored in the specified "nullable" 'object'. Return the value from
85/// // the invocation of 'accessor'. The behavior is undefined if 'object'
86/// // contains a null value.
87///
88/// bool bdlat_nullableValueIsNull(const YOUR_TYPE& object);
89/// // Return 'true' if the specified "nullable" 'object' contains a null
90/// // value, and 'false' otherwise.
91/// @endcode
92/// The "nullable" type must also define two meta-functions in the
93/// `bdlat_NullableValueFunctions` namespace:
94///
95/// * the meta-function `IsNullableValue` contains a compile-time constant
96/// `value` that is non-zero if the parameterized `TYPE` exposes "nullable"
97/// behavior, and
98/// * the `ValueType` meta-function contains a `typedef` `Type` that specifies
99/// the type of the value that can be stored in the parameterized "nullable"
100/// type.
101///
102/// Note that `bdlb::NullableValue<TYPE>` is already part of the `bldat`
103/// infrastructure for "nullable" types because this component also provides
104/// overloads of the required functions and meta-function specializations.
105///
106/// ## Usage {#bdlat_nullablevaluefunctions-usage}
107///
108///
109/// This section illustrates intended use of this component.
110///
111/// ### Example 1: Defining a "Nullable" Type {#bdlat_nullablevaluefunctions-example-1-defining-a-nullable-type}
112///
113///
114/// Suppose you had a type whose value could be in a "null" state.
115///
116/// @code
117/// namespace BloombergLP {
118/// namespace mine {
119///
120/// struct MyNullableValue {
121///
122/// // DATA
123/// bool d_isNull;
124/// int d_value;
125///
126/// // CREATORS
127/// MyNullableValue()
128/// {
129/// d_isNull = true;
130/// }
131/// };
132///
133/// } // close namespace mine
134/// } // close enterprise namespace
135/// @endcode
136/// We can now make `mine::MyNullableValue` expose "nullable" behavior by
137/// implementing the necessary `bdlta_NullableValueFunctions` for
138/// `MyNullableValue` inside the `mine` namespace and defining the required
139/// meta-functions withing the `bdlat_NullableValueFunctions` namespace.
140///
141/// First, we should forward declare all the functions that we will implement
142/// inside the `mine` namespace:
143/// @code
144/// namespace BloombergLP {
145/// namespace mine {
146///
147/// // MANIPULATORS
148/// void bdlat_nullableValueMakeValue(MyNullableValue *object);
149/// // Assign to the specified "nullable" 'object' the default value for
150/// // the contained type (i.e., 'ValueType()').
151///
152/// template <class MANIPULATOR>
153/// int bdlat_nullableValueManipulateValue(MyNullableValue *object,
154/// MANIPULATOR& manipulator);
155/// // Invoke the specified 'manipulator' on the address of the value
156/// // stored in the specified "nullable" 'object'. Return the value from
157/// // the invocation of 'manipulator'. The behavior is undefined if
158/// // 'object' contains a null value.
159///
160/// // ACCESSORS
161/// template <class ACCESSOR>
162/// int bdlat_nullableValueAccessValue(const MyNullableValue& object,
163/// ACCESSOR& accessor);
164/// // Invoke the specified 'accessor' on a 'const'-reference to the value
165/// // stored in the specified "nullable" 'object'. Return the value from
166/// // the invocation of 'accessor'. The behavior is undefined if 'object'
167/// // contains a null value.
168///
169/// bool bdlat_nullableValueIsNull(const MyNullableValue& object);
170/// // Return 'true' if the specified "nullable" 'object' contains a null
171/// // value, and 'false' otherwise.
172///
173/// } // close namespace mine
174/// } // close enterprise namespace
175/// @endcode
176/// Then, we will implement these functions. Recall that the two (non-template)
177/// functions should be defined in some `.cpp` file, unless you choose to make
178/// them `inline` functions.
179/// @code
180/// namespace BloombergLP {
181///
182/// // MANIPULATORS
183/// void mine::bdlat_nullableValueMakeValue(MyNullableValue *object)
184/// {
185/// assert(object);
186///
187/// object->d_isNull = false;
188/// object->d_value = 0;
189/// }
190///
191/// template <class MANIPULATOR>
192/// int mine::bdlat_nullableValueManipulateValue(MyNullableValue *object,
193/// MANIPULATOR& manipulator)
194/// {
195/// assert(object);
196/// assert(!object->d_isNull);
197///
198/// return manipulator(&object->d_value);
199/// }
200///
201/// // ACCESSORS
202/// template <class ACCESSOR>
203/// int mine::bdlat_nullableValueAccessValue(const MyNullableValue& object,
204/// ACCESSOR& accessor)
205/// {
206/// assert(!object.d_isNull);
207///
208/// return accessor(object.d_value);
209/// }
210///
211/// bool mine::bdlat_nullableValueIsNull(const MyNullableValue& object)
212/// {
213/// return object.d_isNull;
214/// }
215///
216/// } // close enterprise namespace
217/// @endcode
218/// Finally, we specialize the `IsNullableValue` and `ValueType` meta-functions
219/// in the `bdlat_NullableValueFunctions` namespace for the
220/// `mine::MyNullableValue` type:
221/// @code
222/// namespace BloombergLP {
223/// namespace bdlat_NullableValueFunctions {
224///
225/// // TRAITS
226/// template <>
227/// struct IsNullableValue<mine::MyNullableValue> : bsl::true_type {
228/// };
229///
230/// template <>
231/// struct ValueType<mine::MyNullableValue> {
232/// typedef int Type;
233/// };
234///
235/// } // close namespace bdlat_NullableValueFunctions
236/// } // close enterprise namespace
237/// @endcode
238/// This completes the `bdlat` infrastructure for `mine::MyNullableValue` and
239/// allows the generic software to recognize the type as a nullable abstraction.
240///
241/// ### Example 2: Using the Infrastructure Via General Methods {#bdlat_nullablevaluefunctions-example-2-using-the-infrastructure-via-general-methods}
242///
243///
244/// The `bdlat` "nullable" framework provides a set of fundamental operations
245/// common to any "nullable" type. We can build upon these operations to make
246/// our own utilities, or use them on our own types that are plugged into the
247/// framework, like `mine::MyNullableValue`, which we created in {Example 1}.
248/// For example, we can use the (fundamental) operations in the
249/// `bdlat_NullableValueFunctions` namespace to operate on
250/// `mine::NullableValue`, even though they have no knowledge of that type in
251/// particular:
252///
253/// Two of those operations are rather basic. One simply informs whether or not
254/// an object is in the null state (the `isNull` method). Another sets an
255/// object to a default, non-null state (the `makeValue` method).
256/// @code
257/// void usageMakeObject()
258/// {
259/// BSLMF_ASSERT(bdlat_NullableValueFunctions::
260/// IsNullableValue<mine::MyNullableValue>::value);
261///
262/// mine::MyNullableValue object;
263/// assert( bdlat_NullableValueFunctions::isNull(object));
264///
265/// bdlat_NullableValueFunctions::makeValue(&object);
266/// assert(!bdlat_NullableValueFunctions::isNull(object));
267/// }
268/// @endcode
269/// The other two generic methods accomplish their actions via user-supplied
270/// functors.
271///
272/// Let us define a generic functor that gives us access to the underlying value
273/// of the "nullable" type, if it's not null:
274/// @code
275/// template <class VALUE_TYPE>
276/// class GetValueAccessor {
277///
278/// // DATA
279/// VALUE_TYPE *d_value_p;
280///
281/// public:
282/// // CREATORS
283/// explicit GetValueAccessor(VALUE_TYPE *value)
284/// : d_value_p(value)
285/// {
286/// }
287///
288/// // MANIPULATORS
289/// int operator()(const VALUE_TYPE& containedValue)
290/// // Assign the value of the specified 'containedValue' to the object
291/// // addressed by 'd_value_p'.
292/// {
293/// *d_value_p = containedValue;
294/// return 0;
295/// }
296/// };
297/// @endcode
298/// Notice that the above class makes no assumptions about the value being
299/// accessed other than it can be copied (in the constructor) and assigned (in
300/// the operator).
301///
302/// This functor can be used to fetch the value of our nullable object:
303/// @code
304/// void usageGetValue()
305/// {
306/// mine::MyNullableValue object;
307///
308/// bdlat_NullableValueFunctions::makeValue(&object);
309/// assert(!bdlat_NullableValueFunctions::isNull(object));
310///
311/// int value;
312/// GetValueAccessor<int> accessor(&value);
313///
314/// int rc = bdlat_NullableValueFunctions::accessValue(object, accessor);
315/// assert(0 == rc);
316/// assert(0 == value);
317/// }
318/// @endcode
319/// Notice that we did not invoke `accessValue` until `object` had been set to a
320/// non-null state. Doing otherwise would have led to undefined behavior.
321///
322/// Finally, let's define a functor to set the state of a nullable object:
323/// @code
324/// template <class VALUE_TYPE>
325/// class SetValueManipulator {
326///
327/// // DATA
328/// VALUE_TYPE d_value;
329///
330/// public:
331/// // CREATORS
332/// explicit SetValueManipulator(const VALUE_TYPE& value)
333/// : d_value(value)
334/// {
335/// }
336///
337/// // ACCESSOR
338/// int operator()(VALUE_TYPE *value) const
339/// {
340/// *value = d_value;
341/// return 0;
342/// }
343/// };
344/// @endcode
345/// As with the previous functor, this functor has no knowledge of the nullable
346/// type to which it will be applied. The only assumption here is that the
347/// value (type) of our nullable type can be copy constructed and copy assigned.
348///
349/// Let us use this functor to modify one of our nullable objects:
350/// @code
351/// void usageSetValue()
352/// {
353/// mine::MyNullableValue object;
354///
355/// bdlat_NullableValueFunctions::makeValue(&object);
356/// assert(!bdlat_NullableValueFunctions::isNull(object));
357///
358/// SetValueManipulator<int> manipulator(42);
359/// int rcm = bdlat_NullableValueFunctions::manipulateValue(&object,
360/// manipulator);
361/// assert(0 == rcm);
362///
363/// // Confirm that the object was set to the expected state.
364///
365/// int value;
366/// GetValueAccessor<int> accessor(&value);
367///
368/// int rca = bdlat_NullableValueFunctions::accessValue(object, accessor);
369/// assert( 0 == rca);
370/// assert(42 == value);
371/// }
372/// @endcode
373///
374/// ### Example 3: Defining Utility Functions {#bdlat_nullablevaluefunctions-example-3-defining-utility-functions}
375///
376///
377/// Creating functor objects for each operation can be tedious and error prone;
378/// consequently, those types are often executed via utility functions.
379///
380/// Suppose we want to create utilities for getting and setting the value
381/// associated with an arbitrary "nullable" type.
382///
383/// These functors make minimal assumptions of `VALUE_TYPE`, merely that it is
384/// copy constructable and copy assignable.
385///
386/// @code
387/// struct NullableValueUtil {
388///
389/// // CLASS METHODS
390/// template <class NULLABLE_VALUE_TYPE>
391/// static int getValue(
392/// typename bdlat_NullableValueFunctions
393/// ::ValueType<NULLABLE_VALUE_TYPE>::Type *value,
394/// const NULLABLE_VALUE_TYPE& object)
395/// // Load to the specified 'value' the value of the specified
396/// // nullable value 'object'. This function template requires that
397/// // the specified 'NULLABLE_VALUE_TYPE' is a 'bdlat' "nullable"
398/// // type. The behavior is undefined unless 'object' is in a
399/// // non-null state (i.e.,
400/// // 'false == bdlat_NullableValueFunctions::isNull(object))'.
401/// {
402/// BSLMF_ASSERT(bdlat_NullableValueFunctions
403/// ::IsNullableValue<NULLABLE_VALUE_TYPE>::value);
404///
405/// BSLS_ASSERT(!bdlat_NullableValueFunctions::isNull(object));
406///
407/// typedef typename bdlat_NullableValueFunctions
408/// ::ValueType<NULLABLE_VALUE_TYPE>::Type ValueType;
409///
410/// GetValueAccessor<ValueType> valueAccessor(value);
411/// return bdlat_NullableValueFunctions::accessValue(object,
412/// valueAccessor);
413/// }
414///
415/// template <class NULLABLE_VALUE_TYPE>
416/// static int setValue(NULLABLE_VALUE_TYPE *object,
417/// const typename bdlat_NullableValueFunctions
418/// ::ValueType<NULLABLE_VALUE_TYPE>::Type& value)
419/// // Set the value of the specified 'object' to the specified
420/// // 'value'. This function template requires that the specified
421/// // 'NULLABLE_VALUE_TYPE' is a 'bdlat' "nullable" type. The
422/// // behavior is undefined unless 'object' is in a non-null state
423/// // (i.e., 'false == bdlat_NullableValueFunctions::isNull(object))'.
424/// // Note that a "nullable" object can be put into a non-null state
425/// // by the 'bdlat_NullableValueFunctions::makeValue' function
426/// // overload for the 'NULLABLE_VALUE_TYPE'.
427/// {
428/// BSLMF_ASSERT(bdlat_NullableValueFunctions
429/// ::IsNullableValue<NULLABLE_VALUE_TYPE>::value);
430///
431/// BSLS_ASSERT(object);
432/// BSLS_ASSERT(!bdlat_NullableValueFunctions::isNull(*object));
433///
434/// typedef typename bdlat_NullableValueFunctions
435/// ::ValueType<NULLABLE_VALUE_TYPE>::Type ValueType;
436///
437/// SetValueManipulator<ValueType> manipulator(value);
438/// return bdlat_NullableValueFunctions::manipulateValue(object,
439/// manipulator);
440/// }
441/// };
442/// @endcode
443/// Now, we can use these functors to write generic utility functions for
444/// getting and setting the value types of arbitrary "nullable" classes.
445/// @code
446/// void myUsageScenario()
447/// {
448/// mine::MyNullableValue object;
449/// assert(bdlat_NullableValueFunctions::isNull(object));
450///
451/// bdlat_NullableValueFunctions::makeValue(&object);
452/// assert(!bdlat_NullableValueFunctions::isNull(object));
453///
454/// typedef
455/// bdlat_NullableValueFunctions::ValueType<mine::MyNullableValue>::Type
456/// MyValueType;
457///
458/// int rcs = NullableValueUtil::setValue(&object, MyValueType(42));
459/// assert(0 == rcs);
460///
461/// MyValueType value;
462/// int rcg = NullableValueUtil::getValue(&value, object);
463/// assert( 0 == rcg);
464/// assert(42 == value);
465/// }
466/// @endcode
467///
468/// ### Example 4: Achieving Type Independence {#bdlat_nullablevaluefunctions-example-4-achieving-type-independence}
469///
470///
471/// Finally, suppose we have another type such as `your::YourNullableType`,
472/// shown below:
473/// @code
474/// namespace BloombergLP {
475/// namespace your {
476///
477/// class YourNullableValue {
478///
479/// // DATA
480/// bool d_isNull;
481/// bsl::string d_value;
482///
483/// public:
484/// // CREATORS
485/// YourNullableValue()
486/// : d_isNull(true)
487/// , d_value()
488/// {
489/// }
490///
491/// // MANIPULATORS
492/// void makeValue()
493/// {
494/// d_isNull = false;
495/// d_value.clear();
496/// }
497///
498/// void makeNull()
499/// {
500/// d_isNull = true;
501/// d_value.clear();
502/// }
503///
504/// bsl::string& value()
505/// {
506/// assert(!d_isNull);
507///
508/// return d_value;
509/// }
510///
511/// // ACCESSORS
512/// const bsl::string& value() const
513/// {
514/// assert(!d_isNull);
515///
516/// return d_value;
517/// }
518/// bool isNull() const
519/// {
520/// return d_isNull;
521/// }
522/// };
523///
524/// } // close namespace your
525/// } // close enterprise namespace
526/// @endcode
527/// Notice that while there are many similarities to `mine::MyNullableValue`
528/// there are clearly differences:
529/// * The value type is `bsl::string`, not `int`.
530/// * Attributes are accessed via accessor methods, not public data members.
531///
532/// Nevertheless, since `your::YourNullableValue` also provides the functions
533/// and types expected by the `bdlat` infrastructure (not shown) we can
534/// successfully use `your::YourNullableValue` value instead of
535/// `mine::MyNullableValue` in the previous usage scenario, with no other
536/// changes:
537/// @code
538/// void yourUsageScenario()
539/// {
540/// your::YourNullableValue object; // YOUR NULLABLE TYPE
541/// assert(bdlat_NullableValueFunctions::isNull(object));
542///
543/// bdlat_NullableValueFunctions::makeValue(&object);
544/// assert(!bdlat_NullableValueFunctions::isNull(object));
545///
546/// typedef
547/// bdlat_NullableValueFunctions::ValueType<your::YourNullableValue>::Type
548/// YourValueType;
549///
550/// int rcs = NullableValueUtil::setValue(&object, YourValueType("NB"));
551/// assert(0 == rcs);
552///
553/// YourValueType value;
554/// int rcg = NullableValueUtil::getValue(&value, object);
555/// assert( 0 == rcg);
556/// assert("NB" == value);
557/// }
558/// @endcode
559/// Notice that syntax and order of `bdlat_NullableValueFunction` functions
560/// calls have not been changed. The only difference is that the contained
561/// type has changed from `int` to `bsl::string`.
562///
563/// Finally, instead of defining a new "nullable" type, we could substitute the
564/// existing type template `bdlb::NullableValue`. Note that this component
565/// provides specializations of the `bdlat_nullableValueFunctions` for that
566/// type. Since the accessor and manipulator functions we created earlier are
567/// type neutral, we can simply drop `bdlb::NullableValue<float>` into our
568/// familiar scenario:
569/// @code
570/// void anotherUsageScenario()
571/// {
572/// bdlb::NullableValue<float> object; // BDE NULLABLE TYPE
573/// assert(bdlat_NullableValueFunctions::isNull(object));
574///
575/// bdlat_NullableValueFunctions::makeValue(&object);
576/// assert(!bdlat_NullableValueFunctions::isNull(object));
577///
578/// typedef
579/// bdlat_NullableValueFunctions::ValueType<bdlb::NullableValue<float> >
580/// ::Type AnotherValueType;
581///
582/// int rcs = NullableValueUtil::setValue(&object, AnotherValueType(2.0));
583/// assert(0 == rcs);
584///
585/// AnotherValueType value;
586/// int rcg = NullableValueUtil::getValue(&value, object);
587/// assert(0 == rcg);
588/// assert(2.0 == value);
589/// }
590/// @endcode
591/// @}
592/** @} */
593/** @} */
594
595/** @addtogroup bdl
596 * @{
597 */
598/** @addtogroup bdlat
599 * @{
600 */
601/** @addtogroup bdlat_nullablevaluefunctions
602 * @{
603 */
604
605#include <bdlscm_version.h>
606
608
609#include <bsls_assert.h>
610#include <bsls_review.h>
611
612#include <bdlat_bdeatoverrides.h>
613
614#include <bdlb_nullablevalue.h>
616
617#include <bslmf_matchanytype.h>
618
619
620
621 // ======================================
622 // namespace bdlat_NullableValueFunctions
623 // ======================================
624
626 // This 'namespace' provides functions that expose "nullable" behavior for
627 // "nullable" types. See the component-level documentation for more
628 // information.
629
630 // META-FUNCTIONS
631
632 /// This `struct` should be specialized for third-party types that need
633 /// to expose "nullable" behavior. See the component-level
634 /// documentation for further information.
635 template <class TYPE>
638
639 /// This meta-function should contain a typedef `Type` that specifies
640 /// the type of value stored in a nullable type of the parameterized
641 /// `TYPE`.
642 template <class TYPE>
643 struct ValueType;
644
645 // MANIPULATORS
646
647 /// Assign to the specified "nullable" `object` the default value for
648 /// the contained type.
649 template <class TYPE>
650 void makeValue(TYPE *object);
651
652 /// Invoke the specified `manipulator` on the address of the value
653 /// stored in the specified "nullable" `object`. Return the value from
654 /// the invocation of `manipulator`. The behavior is undefined unless
655 /// `object` does not contain a null value.
656 template <class TYPE, class MANIPULATOR>
657 int manipulateValue(TYPE *object,
658 MANIPULATOR& manipulator);
659
660 // ACCESSORS
661
662 /// Invoke the specified `accessor` on the non-modifiable value stored
663 /// in the specified "nullable" `object`. Return the value from the
664 /// invocation of `accessor`. The behavior is undefined unless `object`
665 /// does not contain a null value.
666 template <class TYPE, class ACCESSOR>
667 int accessValue(const TYPE& object,
668 ACCESSOR& accessor);
669
670 /// Return `true` if the specified "nullable" `object` contains a null
671 /// value, and `false` otherwise.
672 template <class TYPE>
673 bool isNull(const TYPE& object);
674
675} // close namespace bdlat_NullableValueFunctions
676
677 // ================================
678 // bdlb::NullableValue declarations
679 // ================================
680
682 // This namespace declaration adds the implementation of the "nullable
683 // value" traits for 'bdlb::NullableValue' to
684 // 'bdlat_NullableValueFunctions'. Note that 'bdlb::NullableValue' is the
685 // first of two canonical "nullable value" types.
686
687 // META-FUNCTIONS
688 template <class TYPE>
689 struct IsNullableValue<bdlb::NullableValue<TYPE> > : public bsl::true_type
690 {};
691
692 template <class TYPE>
693 struct ValueType<bdlb::NullableValue<TYPE> > {
694 typedef TYPE Type;
695 };
696
697 // MANIPULATORS
698 template <class TYPE>
700
701 template <class TYPE, class MANIPULATOR>
704 MANIPULATOR& manipulator);
705
706 // ACCESSORS
707 template <class TYPE, class ACCESSOR>
709 const bdlb::NullableValue<TYPE>& object,
710 ACCESSOR& accessor);
711
712 template <class TYPE>
714
715} // close namespace bdlat_NullableValueFunctions
716
717 // =========================================
718 // bdlb::NullableAllocatedValue declarations
719 // =========================================
720
722 // This namespace declaration adds the implementation of the "nullable
723 // value" traits for 'bdlb::NullableAllocatedValue' to
724 // 'bdlat_NullableValueFunctions'. Note that
725 // 'bdlb::NullableAllocatedValue' is the second of two canonical "nullable
726 // value" types.
727
728 // META-FUNCTIONS
729 template <class TYPE>
730 struct IsNullableValue<bdlb::NullableAllocatedValue<TYPE> >
731 : public bsl::true_type {
732 };
733
734 template <class TYPE>
735 struct ValueType<bdlb::NullableAllocatedValue<TYPE> > {
736 typedef TYPE Type;
737 };
738
739 // MANIPULATORS
740 template <class TYPE>
743
744 template <class TYPE, class MANIPULATOR>
747 MANIPULATOR& manipulator);
748
749 // ACCESSORS
750 template <class TYPE, class ACCESSOR>
753 ACCESSOR& accessor);
754
755 template <class TYPE>
758
759} // close namespace bdlat_NullableValueFunctions
760
761// ============================================================================
762// INLINE DEFINITIONS
763// ============================================================================
764
765 // --------------------------------------
766 // namespace bdlat_NullableValueFunctions
767 // --------------------------------------
768
769// MANIPULATORS
770template <class TYPE>
771inline
773{
774 bdlat_nullableValueMakeValue(object);
775}
776
777template <class TYPE, class MANIPULATOR>
778inline
780 MANIPULATOR& manipulator)
781{
782 return bdlat_nullableValueManipulateValue(object, manipulator);
783}
784
785// ACCESSORS
786template <class TYPE, class ACCESSOR>
787inline
788int bdlat_NullableValueFunctions::accessValue(const TYPE& object,
789 ACCESSOR& accessor)
790{
791 return bdlat_nullableValueAccessValue(object, accessor);
792}
793
794template <class TYPE>
795inline
796bool bdlat_NullableValueFunctions::isNull(const TYPE& object)
797{
798 return bdlat_nullableValueIsNull(object);
799}
800
801 // -------------------------------
802 // bdlb::NullableValue definitions
803 // -------------------------------
804
805// MANIPULATORS
806template <class TYPE>
807inline
810{
811 object->makeValue();
812}
813
814template <class TYPE, class MANIPULATOR>
815inline
818 MANIPULATOR& manipulator)
819{
820 BSLS_ASSERT(!object->isNull());
821
822 return manipulator(&object->value());
823}
824
825// ACCESSORS
826template <class TYPE, class ACCESSOR>
827inline
829 const bdlb::NullableValue<TYPE>& object,
830 ACCESSOR& accessor)
831{
832 BSLS_ASSERT(!object.isNull());
833
834 return accessor(object.value());
835}
836
837template <class TYPE>
838inline
840 const bdlb::NullableValue<TYPE>& object)
841{
842 return object.isNull();
843}
844
845 // ----------------------------------------
846 // bdlb::NullableAllocatedValue definitions
847 // ----------------------------------------
848
849// MANIPULATORS
850template <class TYPE>
851inline
854{
855 object->makeValue();
856}
857
858template <class TYPE, class MANIPULATOR>
859inline
862 MANIPULATOR& manipulator)
863{
864 BSLS_ASSERT(!object->isNull());
865
866 return manipulator(&object->value());
867}
868
869// ACCESSORS
870template <class TYPE, class ACCESSOR>
871inline
874 ACCESSOR& accessor)
875{
876 BSLS_ASSERT(!object.isNull());
877
878 return accessor(object.value());
879}
880
881template <class TYPE>
882inline
885{
886 return object.isNull();
887}
888
889
890
891#endif
892
893// ----------------------------------------------------------------------------
894// Copyright 2015 Bloomberg Finance L.P.
895//
896// Licensed under the Apache License, Version 2.0 (the "License");
897// you may not use this file except in compliance with the License.
898// You may obtain a copy of the License at
899//
900// http://www.apache.org/licenses/LICENSE-2.0
901//
902// Unless required by applicable law or agreed to in writing, software
903// distributed under the License is distributed on an "AS IS" BASIS,
904// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
905// See the License for the specific language governing permissions and
906// limitations under the License.
907// ----------------------------- END-OF-FILE ----------------------------------
908
909/** @} */
910/** @} */
911/** @} */
Definition bdlb_nullableallocatedvalue.h:174
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Definition bdlb_nullableallocatedvalue.h:1356
TYPE & value()
Definition bdlb_nullableallocatedvalue.h:1139
Definition bdlb_nullablevalue.h:257
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Return true if this object is null, and false otherwise.
Definition bdlb_nullablevalue.h:1779
TYPE & value()
Definition bdlb_nullablevalue.h:1742
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlat_nullablevaluefunctions.h:625
bool isNull(const TYPE &object)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
void bdlat_nullableValueMakeValue(bdlb::NullableValue< TYPE > *object)
int accessValue(const TYPE &object, ACCESSOR &accessor)
bool bdlat_nullableValueIsNull(const bdlb::NullableValue< TYPE > &object)
int bdlat_nullableValueAccessValue(const bdlb::NullableValue< TYPE > &object, ACCESSOR &accessor)
int bdlat_nullableValueManipulateValue(bdlb::NullableValue< TYPE > *object, MANIPULATOR &manipulator)
void makeValue(TYPE *object)
Definition bdlb_algorithmworkaroundutil.h:74
Definition bdlat_nullablevaluefunctions.h:636
TYPE Type
Definition bdlat_nullablevaluefunctions.h:694
Definition bdlat_nullablevaluefunctions.h:643
Definition bslmf_integralconstant.h:244