BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlat_nullablevalueutil.h
Go to the documentation of this file.
1/// @file bdlat_nullablevalueutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_nullablevalueutil.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_NULLABLEVALUEUTIL
9#define INCLUDED_BDLAT_NULLABLEVALUEUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_nullablevalueutil bdlat_nullablevalueutil
15/// @brief Provide utilities for operating on `bdlat` "nullable value" types.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_nullablevalueutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_nullablevalueutil-purpose"> Purpose</a>
25/// * <a href="#bdlat_nullablevalueutil-classes"> Classes </a>
26/// * <a href="#bdlat_nullablevalueutil-description"> Description </a>
27/// * <a href="#bdlat_nullablevalueutil-primitive-and-derived-functions-of-nullable-values"> Primitive and Derived Functions of Nullable Values </a>
28/// * <a href="#bdlat_nullablevalueutil-usage"> Usage </a>
29/// * <a href="#bdlat_nullablevalueutil-example-1-accessing-the-held-value-and-its-category"> Example 1: Accessing the Held Value And Its Category </a>
30///
31/// # Purpose {#bdlat_nullablevalueutil-purpose}
32/// Provide utilities for operating on `bdlat` "nullable value" types.
33///
34/// # Classes {#bdlat_nullablevalueutil-classes}
35///
36/// - bdlat::NullableValueUtil: namespace for utility functions on nullables
37///
38/// @see bdlat_nullablevaluefunctions, bdlat_typecategory
39///
40/// # Description {#bdlat_nullablevalueutil-description}
41/// This component provides a utility `struct`,
42/// `bdlat::NullableValueUtil`, which serves as a namespace for a collection of
43/// function templates providing derived operations for "nullable value" types.
44/// See @ref bdlat_nullablevaluefunctions for the set of requirements of
45/// "nullable value" types in the `bdlat` framework. See @ref bdlat_typecategory
46/// for more general information about this framework.
47///
48/// ## Primitive and Derived Functions of Nullable Values {#bdlat_nullablevalueutil-primitive-and-derived-functions-of-nullable-values}
49///
50///
51/// In order to be "plugged in" to the `bdlat` framework as a "nullable value",
52/// a type must meet a set of requirements including providing certain function
53/// overloads (customization points) and specifying certain type traits, as
54/// specified by the @ref bdlat_nullablevaluefunctions component. We call the
55/// required function overloads the "primitive" operations of "nullable value"
56/// types. This component provides "derived" operations, which are operations
57/// that are exclusively defined in terms of primitive operations, and as such
58/// can be used with any "nullable value" type.
59///
60/// ## Usage {#bdlat_nullablevalueutil-usage}
61///
62///
63/// In this section we show intended usage of this component.
64///
65/// ### Example 1: Accessing the Held Value And Its Category {#bdlat_nullablevalueutil-example-1-accessing-the-held-value-and-its-category}
66///
67///
68/// Suppose we would like to define a function that detects whether the value
69/// held by a nullable value is an array.
70///
71/// First, we need to define an accessor functor per
72/// {@ref bdlat_typecategory |`ACCESSOR` Functors} that will be used to detect
73/// whether the held value is an array:
74/// @code
75/// class MyArrayDetector {
76/// // DATA
77/// bool d_didVisitArray;
78///
79/// public:
80/// // CREATORS
81/// MyArrayDetector()
82/// : d_didVisitArray(false)
83/// {
84/// }
85///
86/// // MANIPULATORS
87/// template <class TYPE>
88/// int operator()(const TYPE& object, bdlat_TypeCategory::Array)
89/// {
90/// d_didVisitArray = true;
91/// return 0;
92/// }
93///
94/// template <class TYPE, class OTHER_CATEGORY>
95/// int operator()(const TYPE&, OTHER_CATEGORY)
96/// {
97/// d_didVisitArray = false;
98/// return 0;
99/// }
100///
101/// // ACCESSORS
102/// bool didVisitArray()
103/// {
104/// return d_didVisitArray;
105/// }
106/// };
107/// @endcode
108/// Then, we can define a utility `struct`, `MyNullableValueUtil`, that provides
109/// a function for detecting whether or not the held value of a nullable value
110/// is an array:
111/// @code
112/// struct MyNullableValueUtil {
113///
114/// // CLASS METHODS
115/// template <class TYPE>
116/// static int isValueAnArray(bool *isArray, const TYPE& object)
117/// // Load the value 'true' to the specified 'isArray' if the value
118/// // stored in the specified 'object' has the "array" type category,
119/// // and load the value 'false' otherwise. Return 0 on success,
120/// // and a non-zero value otherwise. If a non-zero value is
121/// // returned, the value loaded to 'isArray' is unspecified. The
122/// // behavior is undefined if 'object' contains a null value.
123/// {
124/// BSLS_ASSERT(bdlat_TypeCategoryFunctions::select(object) ==
125/// bdlat_TypeCategory::e_NULLABLE_VALUE_CATEGORY);
126/// BSLS_ASSERT(!bdlat_NullableValueFunctions::isNull(object));
127///
128/// MyArrayDetector detector;
129/// int rc = bdlat::NullableValueUtil::accessValueByCategory(object,
130/// detector);
131/// if (0 != rc) {
132/// return -1; // RETURN
133/// }
134///
135/// *isArray = detector.didVisitArray();
136/// return 0;
137/// }
138/// };
139/// @endcode
140/// Finally, we can use this utility to detect whether nullable values are
141/// arrays:
142/// @code
143/// void example()
144/// {
145/// bdlb::NullableValue<int> valueA(42);
146///
147/// bool isArray = false;
148/// int rc = MyNullableValueUtil::isValueAnArray(&isArray, valueA);
149///
150/// assert(0 == rc);
151/// assert(! isArray);
152///
153/// bdlb::NullableValue<bsl::vector<int> > valueB;
154/// valueB.makeValue(bsl::vector<int>());
155///
156/// rc = MyNullableValueUtil::isValueAnArray(&isArray, valueB);
157///
158/// assert(0 == rc);
159/// assert(isArray);
160/// }
161/// @endcode
162/// @}
163/** @} */
164/** @} */
165
166/** @addtogroup bdl
167 * @{
168 */
169/** @addtogroup bdlat
170 * @{
171 */
172/** @addtogroup bdlat_nullablevalueutil
173 * @{
174 */
175
176#include <bdlscm_version.h>
177
179#include <bdlat_typecategory.h>
180
181#include <bslmf_assert.h>
183
184
185#include <bsls_assert.h>
186#include <bsls_platform.h>
187
188
189namespace bdlat {
190
191 // ========================
192 // struct NullableValueUtil
193 // ========================
194
195/// This `struct` provides a namespace for a suite of function templates
196/// providing non-primitive operations on "nullable value" types.
198
199 private:
200 // PRIVATE TYPES
201
202 /// This private class provides a function-object type that adapts a
203 /// (categorized) accessor functor to an uncategorized accessor functor.
204 /// For the definition of an accessor functor, see
205 /// {@ref bdlat_typecategory |`ACCESSOR` Functors}. An uncategorized
206 /// accessor functor is one that does not take a second, `category`,
207 /// argument, such as a functor that may be passed to
208 /// `bdlat_NullableValueFunctions::accessValue`, for example.
209 template <class ACCESSOR>
210 class AccessByCategoryAdapter;
211
212 /// This private class provides a function-object type that adapts a
213 /// (categorized) manipulator functor to an uncategorized manipulator
214 /// functor. For the definition of a manipulator functor, see
215 /// {@ref bdlat_typecategory |`MANIPULATOR` Functors}. An uncategorized
216 /// manipulator functor is one that does not take a second, `category`,
217 /// argument, such as a functor that may be passed to
218 /// `bdlat_NullableValueFunctions::manipulateValue`, for example.
219 template <class MANIPULATOR>
220 class ManipulateByCategoryAdapter;
221
222 public:
223 // CLASS METHODS
224
225 /// Invoke the specified `accessor` on the non-modifiable value
226 /// stored in the specified "nullable" `object` and on a prvalue of
227 /// the category tag type for the dynamic category of the value. See
228 /// {@ref bdlat_typecategory |Category Tags and Enumerators} for
229 /// documentation about category tags. Return the value from the
230 /// invocation of `accessor`. The `accessor` must be an accessor
231 /// functor. See {@ref bdlat_typecategory |`ACCESSOR` Functors} for the
232 /// requirements on `accessor`. The behavior is undefined if `object`
233 /// contains a null value.
234 template <class TYPE, class ACCESSOR>
235 static int accessValueByCategory(const TYPE& object, ACCESSOR& accessor);
236
237 /// Invoke the specified `manipulator` on the address of the value
238 /// stored in the specified "nullable" `object` and on a prvalue of
239 /// the category tag type for the dynamic category of the value. See
240 /// {@ref bdlat_typecategory |Category Tags and Enumerators} for
241 /// documentation about category tags. Return the value from the
242 /// invocation of `manipulator`. The `manipulator` must be a
243 /// manipulator functor. See
244 /// {@ref bdlat_typecategory |`MANIPULATOR` Functors}
245 /// for the requirements on `manipulator`. The behavior is undefined if
246 /// `object` contains a null value.
247 template <class TYPE, class MANIPULATOR>
248 static int manipulateValueByCategory(TYPE *object,
249 MANIPULATOR& manipulator);
250};
251
252 // ================================================
253 // class NullableValueUtil::AccessByCategoryAdapter
254 // ================================================
255
256/// See the class-level documentation of `NullableValueUtil` for the
257/// description of this component-private class template.
258template <class ACCESSOR>
259class NullableValueUtil::AccessByCategoryAdapter {
260
261 // DATA
262
263 // The `accessor` attribute of this object.
264 ACCESSOR *d_accessor_p;
265
266 public:
267 // CREATORS
268
269 /// Create an `AccessByCategoryAdapter` object having the specified
270 /// `accessor` attribute.
271 explicit AccessByCategoryAdapter(ACCESSOR *accessor);
272
273 // ACCESSORS
274
275 /// Invoke the `accessor` of this object with the specified `value` and
276 /// a prvalue of the category tag type for its dynamic category. Return
277 /// the value from the invocation of `accessor`.
278 template <class VALUE_TYPE>
279 int operator()(const VALUE_TYPE& value) const;
280};
281
282 // ====================================================
283 // class NullableValueUtil::ManipulateByCategoryAdapter
284 // ====================================================
285
286/// See the class-level documentation of `NullableValueUtil` for the
287/// description of this component-private class template.
288template <class MANIPULATOR>
289class NullableValueUtil::ManipulateByCategoryAdapter {
290
291 // DATA
292
293 // The `manipulator` attribute of this object.
294 MANIPULATOR *d_manipulator_p;
295
296 public:
297 // CREATORS
298
299 /// Create a `ManipulateByCategory` object having the specified
300 /// `manipulator` attribute value.
301 explicit ManipulateByCategoryAdapter(MANIPULATOR *manipulator);
302
303 // ACCESSORS
304
305 /// Invoke the `manipulator` of this object with the specified `value`
306 /// and a prvalue of the category tag type for its dynamic category.
307 /// Return the value from the invocation of the `manipulator`.
308 template <class VALUE_TYPE>
309 int operator()(VALUE_TYPE *value) const;
310};
311
312// ============================================================================
313// INLINE DEFINITIONS
314// ============================================================================
315
316 // -----------------------
317 // class NullableValueUtil
318 // -----------------------
319
320// CLASS METHODS
321template <class TYPE, class ACCESSOR>
322inline
324 ACCESSOR& accessor)
325{
326#if !defined(BSLS_PLATFORM_CMP_SUN)
328#endif
332
333 const NullableValueUtil::AccessByCategoryAdapter<ACCESSOR> adapter(
334 &accessor);
335 return bdlat_NullableValueFunctions::accessValue(object, adapter);
336}
337
338template <class TYPE, class MANIPULATOR>
339inline
341 MANIPULATOR& manipulator)
342{
343#if !defined(BSLS_PLATFORM_CMP_SUN)
345#endif
346 BSLS_ASSERT(object);
350
351 const NullableValueUtil::ManipulateByCategoryAdapter<MANIPULATOR> adapter(
352 &manipulator);
353 return bdlat_NullableValueFunctions::manipulateValue(object, adapter);
354}
355
356 // ------------------------------------------------
357 // class NullableValueUtil::AccessByCategoryAdapter
358 // ------------------------------------------------
359
360// CREATORS
361template <class ACCESSOR>
362inline
363NullableValueUtil::AccessByCategoryAdapter<ACCESSOR>::AccessByCategoryAdapter(
364 ACCESSOR *accessor)
365: d_accessor_p(accessor)
366{
367}
368
369// ACCESSORS
370template <class ACCESSOR>
371template <class VALUE_TYPE>
372inline
373int NullableValueUtil::AccessByCategoryAdapter<ACCESSOR>::operator()(
374 const VALUE_TYPE& value) const
375{
376 return bdlat_TypeCategoryUtil::accessByCategory(value, *d_accessor_p);
377}
378
379 // ----------------------------------------------------
380 // class NullableValueUtil::ManipulateByCategoryAdapter
381 // ----------------------------------------------------
382
383// CREATORS
384template <class MANIPULATOR>
385inline
386NullableValueUtil::ManipulateByCategoryAdapter<
387 MANIPULATOR>::ManipulateByCategoryAdapter(MANIPULATOR *manipulator)
388: d_manipulator_p(manipulator)
389{
390}
391
392// ACCESSORS
393template <class MANIPULATOR>
394template <class VALUE_TYPE>
395inline
396int NullableValueUtil::ManipulateByCategoryAdapter<MANIPULATOR>::operator()(
397 VALUE_TYPE *value) const
398{
400 *d_manipulator_p);
401}
402
403} // close package namespace
404
405
406#endif // INCLUDED_BDLAT_NULLABLEVALUEUTIL
407
408// ----------------------------------------------------------------------------
409// Copyright 2022 Bloomberg Finance L.P.
410//
411// Licensed under the Apache License, Version 2.0 (the "License");
412// you may not use this file except in compliance with the License.
413// You may obtain a copy of the License at
414//
415// http://www.apache.org/licenses/LICENSE-2.0
416//
417// Unless required by applicable law or agreed to in writing, software
418// distributed under the License is distributed on an "AS IS" BASIS,
419// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
420// See the License for the specific language governing permissions and
421// limitations under the License.
422// ----------------------------- END-OF-FILE ----------------------------------
423
424/** @} */
425/** @} */
426/** @} */
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1404
static int accessByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_typecategory.h:1444
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:229
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
bool isNull(const TYPE &object)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
int accessValue(const TYPE &object, ACCESSOR &accessor)
bdlat_TypeCategory::Value select(const TYPE &object)
Definition bdlat_arrayutil.h:198
Definition bdlat_nullablevalueutil.h:197
static int manipulateValueByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_nullablevalueutil.h:340
static int accessValueByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_nullablevalueutil.h:323
Definition bdlat_nullablevaluefunctions.h:636
@ e_NULLABLE_VALUE_CATEGORY
Definition bdlat_typecategory.h:1050