BDE 4.39.x 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///
116/// /// Load the value `true` to the specified `isArray` if the value
117/// /// stored in the specified `object` has the "array" type category,
118/// /// and load the value `false` otherwise. Return 0 on success,
119/// /// and a non-zero value otherwise. If a non-zero value is
120/// /// returned, the value loaded to `isArray` is unspecified. The
121/// /// behavior is undefined if `object` contains a null value.
122/// template <class TYPE>
123/// static int isValueAnArray(bool *isArray, const TYPE& object)
124/// {
125/// BSLS_ASSERT(bdlat_TypeCategoryFunctions::select(object) ==
126/// bdlat_TypeCategory::e_NULLABLE_VALUE_CATEGORY);
127/// BSLS_ASSERT(!bdlat_NullableValueFunctions::isNull(object));
128///
129/// MyArrayDetector detector;
130/// int rc = bdlat::NullableValueUtil::accessValueByCategory(object,
131/// detector);
132/// if (0 != rc) {
133/// return -1; // RETURN
134/// }
135///
136/// *isArray = detector.didVisitArray();
137/// return 0;
138/// }
139/// };
140/// @endcode
141/// Finally, we can use this utility to detect whether nullable values are
142/// arrays:
143/// @code
144/// void example()
145/// {
146/// bdlb::NullableValue<int> valueA(42);
147///
148/// bool isArray = false;
149/// int rc = MyNullableValueUtil::isValueAnArray(&isArray, valueA);
150///
151/// assert(0 == rc);
152/// assert(! isArray);
153///
154/// bdlb::NullableValue<bsl::vector<int> > valueB;
155/// valueB.makeValue(bsl::vector<int>());
156///
157/// rc = MyNullableValueUtil::isValueAnArray(&isArray, valueB);
158///
159/// assert(0 == rc);
160/// assert(isArray);
161/// }
162/// @endcode
163/// @}
164/** @} */
165/** @} */
166
167/** @addtogroup bdl
168 * @{
169 */
170/** @addtogroup bdlat
171 * @{
172 */
173/** @addtogroup bdlat_nullablevalueutil
174 * @{
175 */
176
177#include <bdlscm_version.h>
178
180#include <bdlat_typecategory.h>
181
182#include <bslmf_assert.h>
184
185
186#include <bsls_assert.h>
187#include <bsls_platform.h>
188
189
190namespace bdlat {
191
192 // ========================
193 // struct NullableValueUtil
194 // ========================
195
196/// This `struct` provides a namespace for a suite of function templates
197/// providing non-primitive operations on "nullable value" types.
198///
199/// See @ref bdlat_nullablevalueutil
201
202 private:
203 // PRIVATE TYPES
204
205 /// This private class provides a function-object type that adapts a
206 /// (categorized) accessor functor to an uncategorized accessor functor.
207 /// For the definition of an accessor functor, see
208 /// {@ref bdlat_typecategory |`ACCESSOR` Functors}. An uncategorized
209 /// accessor functor is one that does not take a second, `category`,
210 /// argument, such as a functor that may be passed to
211 /// `bdlat_NullableValueFunctions::accessValue`, for example.
212 template <class ACCESSOR>
213 class AccessByCategoryAdapter;
214
215 /// This private class provides a function-object type that adapts a
216 /// (categorized) manipulator functor to an uncategorized manipulator
217 /// functor. For the definition of a manipulator functor, see
218 /// {@ref bdlat_typecategory |`MANIPULATOR` Functors}. An uncategorized
219 /// manipulator functor is one that does not take a second, `category`,
220 /// argument, such as a functor that may be passed to
221 /// `bdlat_NullableValueFunctions::manipulateValue`, for example.
222 template <class MANIPULATOR>
223 class ManipulateByCategoryAdapter;
224
225 public:
226 // CLASS METHODS
227
228 /// Invoke the specified `accessor` on the non-modifiable value
229 /// stored in the specified "nullable" `object` and on a prvalue of
230 /// the category tag type for the dynamic category of the value. See
231 /// {@ref bdlat_typecategory |Category Tags and Enumerators} for
232 /// documentation about category tags. Return the value from the
233 /// invocation of `accessor`. The `accessor` must be an accessor
234 /// functor. See {@ref bdlat_typecategory |`ACCESSOR` Functors} for the requirements on `accessor`.
235 ///
236 /// \pre The behavior is undefined if `object`
237 /// contains a null value.
238 template <class TYPE, class ACCESSOR>
239 static int accessValueByCategory(const TYPE& object, ACCESSOR& accessor);
240
241 /// Invoke the specified `manipulator` on the address of the value
242 /// stored in the specified "nullable" `object` and on a prvalue of
243 /// the category tag type for the dynamic category of the value. See
244 /// {@ref bdlat_typecategory |Category Tags and Enumerators} for
245 /// documentation about category tags. Return the value from the
246 /// invocation of `manipulator`. The `manipulator` must be a
247 /// manipulator functor. See
248 /// {@ref bdlat_typecategory |`MANIPULATOR` Functors} for the requirements on `manipulator`.
249 ///
250 /// \pre The behavior is undefined if
251 /// `object` contains a null value.
252 template <class TYPE, class MANIPULATOR>
253 static int manipulateValueByCategory(TYPE *object,
254 MANIPULATOR& manipulator);
255};
256
257 // ================================================
258 // class NullableValueUtil::AccessByCategoryAdapter
259 // ================================================
260
261/// See the class-level documentation of `NullableValueUtil` for the
262/// description of this component-private class template.
263template <class ACCESSOR>
264class NullableValueUtil::AccessByCategoryAdapter {
265
266 // DATA
267
268 // The `accessor` attribute of this object.
269 ACCESSOR *d_accessor_p;
270
271 public:
272 // CREATORS
273
274 /// Create an `AccessByCategoryAdapter` object having the specified
275 /// `accessor` attribute.
276 explicit AccessByCategoryAdapter(ACCESSOR *accessor);
277
278 // ACCESSORS
279
280 /// Invoke the `accessor` of this object with the specified `value` and
281 /// a prvalue of the category tag type for its dynamic category. Return
282 /// the value from the invocation of `accessor`.
283 template <class VALUE_TYPE>
284 int operator()(const VALUE_TYPE& value) const;
285};
286
287 // ====================================================
288 // class NullableValueUtil::ManipulateByCategoryAdapter
289 // ====================================================
290
291/// See the class-level documentation of `NullableValueUtil` for the
292/// description of this component-private class template.
293template <class MANIPULATOR>
294class NullableValueUtil::ManipulateByCategoryAdapter {
295
296 // DATA
297
298 // The `manipulator` attribute of this object.
299 MANIPULATOR *d_manipulator_p;
300
301 public:
302 // CREATORS
303
304 /// Create a `ManipulateByCategory` object having the specified
305 /// `manipulator` attribute value.
306 explicit ManipulateByCategoryAdapter(MANIPULATOR *manipulator);
307
308 // ACCESSORS
309
310 /// Invoke the `manipulator` of this object with the specified `value`
311 /// and a prvalue of the category tag type for its dynamic category.
312 /// Return the value from the invocation of the `manipulator`.
313 template <class VALUE_TYPE>
314 int operator()(VALUE_TYPE *value) const;
315};
316
317// ============================================================================
318// INLINE DEFINITIONS
319// ============================================================================
320
321 // -----------------------
322 // class NullableValueUtil
323 // -----------------------
324
325// CLASS METHODS
326template <class TYPE, class ACCESSOR>
327inline
329 ACCESSOR& accessor)
330{
331#if !defined(BSLS_PLATFORM_CMP_SUN)
333#endif
337
338 const NullableValueUtil::AccessByCategoryAdapter<ACCESSOR> adapter(
339 &accessor);
340 return bdlat_NullableValueFunctions::accessValue(object, adapter);
341}
342
343template <class TYPE, class MANIPULATOR>
344inline
346 MANIPULATOR& manipulator)
347{
348#if !defined(BSLS_PLATFORM_CMP_SUN)
350#endif
351 BSLS_ASSERT(object);
355
356 const NullableValueUtil::ManipulateByCategoryAdapter<MANIPULATOR> adapter(
357 &manipulator);
358 return bdlat_NullableValueFunctions::manipulateValue(object, adapter);
359}
360
361 // ------------------------------------------------
362 // class NullableValueUtil::AccessByCategoryAdapter
363 // ------------------------------------------------
364
365// CREATORS
366template <class ACCESSOR>
367inline
368NullableValueUtil::AccessByCategoryAdapter<ACCESSOR>::AccessByCategoryAdapter(
369 ACCESSOR *accessor)
370: d_accessor_p(accessor)
371{
372}
373
374// ACCESSORS
375template <class ACCESSOR>
376template <class VALUE_TYPE>
377inline
378int NullableValueUtil::AccessByCategoryAdapter<ACCESSOR>::operator()(
379 const VALUE_TYPE& value) const
380{
381 return bdlat_TypeCategoryUtil::accessByCategory(value, *d_accessor_p);
382}
383
384 // ----------------------------------------------------
385 // class NullableValueUtil::ManipulateByCategoryAdapter
386 // ----------------------------------------------------
387
388// CREATORS
389template <class MANIPULATOR>
390inline
391NullableValueUtil::ManipulateByCategoryAdapter<
392 MANIPULATOR>::ManipulateByCategoryAdapter(MANIPULATOR *manipulator)
393: d_manipulator_p(manipulator)
394{
395}
396
397// ACCESSORS
398template <class MANIPULATOR>
399template <class VALUE_TYPE>
400inline
401int NullableValueUtil::ManipulateByCategoryAdapter<MANIPULATOR>::operator()(
402 VALUE_TYPE *value) const
403{
405 *d_manipulator_p);
406}
407
408} // close package namespace
409
410
411#endif // INCLUDED_BDLAT_NULLABLEVALUEUTIL
412
413// ----------------------------------------------------------------------------
414// Copyright 2022 Bloomberg Finance L.P.
415//
416// Licensed under the Apache License, Version 2.0 (the "License");
417// you may not use this file except in compliance with the License.
418// You may obtain a copy of the License at
419//
420// http://www.apache.org/licenses/LICENSE-2.0
421//
422// Unless required by applicable law or agreed to in writing, software
423// distributed under the License is distributed on an "AS IS" BASIS,
424// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
425// See the License for the specific language governing permissions and
426// limitations under the License.
427// ----------------------------- END-OF-FILE ----------------------------------
428
429/** @} */
430/** @} */
431/** @} */
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1414
static int accessByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_typecategory.h:1455
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#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 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:200
static int manipulateValueByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_nullablevalueutil.h:345
static int accessValueByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_nullablevalueutil.h:328
Definition bdlat_nullablevaluefunctions.h:649
@ e_NULLABLE_VALUE_CATEGORY
Definition bdlat_typecategory.h:1052