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