BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlat_sequencefunctions.h
Go to the documentation of this file.
1/// @file bdlat_sequencefunctions.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_sequencefunctions.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_SEQUENCEFUNCTIONS
9#define INCLUDED_BDLAT_SEQUENCEFUNCTIONS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_sequencefunctions bdlat_sequencefunctions
15/// @brief Provide a namespace defining sequence functions.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_sequencefunctions
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_sequencefunctions-purpose"> Purpose</a>
25/// * <a href="#bdlat_sequencefunctions-classes"> Classes </a>
26/// * <a href="#bdlat_sequencefunctions-description"> Description </a>
27/// * <a href="#bdlat_sequencefunctions-usage"> Usage </a>
28/// * <a href="#bdlat_sequencefunctions-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#bdlat_sequencefunctions-purpose}
31/// Provide a namespace defining sequence functions.
32///
33/// # Classes {#bdlat_sequencefunctions-classes}
34///
35/// - bdlat_SequenceFunctions: namespace for calling sequence functions
36///
37/// @see bdlat_attributeinfo
38///
39/// # Description {#bdlat_sequencefunctions-description}
40/// The `bdlat_SequenceFunctions` `namespace` provided in this
41/// component defines parameterized functions that expose "sequence" behavior
42/// for "sequence" types. See the `bdlat` package-level documentation for a
43/// brief description of "sequence" types.
44///
45/// The functions in this namespace allow users to:
46/// * manipulate an attribute by attribute id or attribute name using a
47/// parameterized manipulator (`manipulateAttribute`).
48/// * manipulate all attributes sequentially using a parameterized manipulator
49/// (`manipulateAttributes`).
50/// * access an attribute by attribute id or attribute name using a
51/// parameterized accessor (`accessAttribute`).
52/// * access all attributes sequentially using a parameterized accessor
53/// (`accessAttributes`).
54///
55/// Also, the meta-function `IsSequence` contains a compile-time constant
56/// `value` that is non-zero if the parameterized `TYPE` exposes "sequence"
57/// behavior through the `bdlat_SequenceFunctions` `namespace`.
58///
59/// This component specializes all of these functions for types that have the
60/// `bdlat_TypeTraitBasicSequence` trait.
61///
62/// Types that do not have the `bdlat_TypeTraitBasicSequence` trait can be
63/// plugged into the `bdlat` framework. This is done by overloading the
64/// `bdlat_sequence*` functions inside the namespace of the plugged in type.
65/// Note that the placeholder `YOUR_TYPE` is not a template argument and should
66/// be replaced with the name of the type being plugged into the framework.
67/// @code
68/// // MANIPULATORS
69///
70/// /// Invoke the specified `manipulator` on the address of the (modifiable)
71/// /// attribute indicated by the specified `attributeName` and
72/// /// `attributeNameLength` of the specified `object`, supplying `manipulator`
73/// /// with the corresponding attribute information structure. The supplied
74/// /// `manipulator` must be a callable type that can be called as if it had
75/// /// the following signature:
76/// /// ```
77/// /// template <class t_INFO>
78/// /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
79/// /// ```
80/// /// Return non-zero value if the attribute is not found, and the value
81/// /// returned from the invocation of `manipulator` otherwise.
82/// template <typename MANIPULATOR>
83/// int bdlat_sequenceManipulateAttribute(YOUR_TYPE *object,
84/// MANIPULATOR& manipulator,
85/// const char *attributeName,
86/// int attributeNameLength);
87///
88/// /// Invoke the specified `manipulator` on the address of the (modifiable)
89/// /// attribute indicated by the specified `attributeId` of the specified
90/// /// `object`, supplying `manipulator` with the corresponding attribute
91/// /// information structure. The supplied `manipulator` must be a callable
92/// /// type that can be called as if it had the following signature:
93/// /// ```
94/// /// template <class t_INFO>
95/// /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
96/// /// ```
97/// /// Return non-zero value if the attribute is not found, and the value
98/// /// returned from the invocation of `manipulator` otherwise.
99/// template <typename MANIPULATOR>
100/// int bdlat_sequenceManipulateAttribute(YOUR_TYPE *object,
101/// MANIPULATOR& manipulator,
102/// int attributeId);
103///
104/// /// Invoke the specified `manipulator` sequentially on the address of each
105/// /// (modifiable) attribute of the specified `object`, supplying
106/// /// `manipulator` with the corresponding attribute information structure
107/// /// until such invocation returns non-zero value. The supplied
108/// /// `manipulator` must be a callable type that can be called as if it had
109/// /// the following signature:
110/// /// ```
111/// /// template <class t_INFO>
112/// /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
113/// /// ```
114/// /// Return the value from the last invocation of `manipulator` (i.e., the
115/// /// invocation that terminated the sequence).
116/// template <typename MANIPULATOR>
117/// int bdlat_sequenceManipulateAttributes(YOUR_TYPE *object,
118/// MANIPULATOR& manipulator);
119///
120/// // ACCESSORS
121///
122/// /// Invoke the specified `accessor` on the (non-modifiable) attribute of the
123/// /// specified `object` indicated by the specified `attributeName` and
124/// /// `attributeNameLength`, supplying `accessor` with the corresponding
125/// /// attribute information structure. The supplied `accessor` must be a
126/// /// callable type that can be called as if it had the following signature:
127/// /// ```
128/// /// template <class t_INFO>
129/// /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
130/// /// ```
131/// /// Return non-zero value if the attribute is not found, and the value
132/// /// returned from the invocation of `accessor` otherwise.
133/// template <typename ACCESSOR>
134/// int bdlat_sequenceAccessAttribute(const YOUR_TYPE& object,
135/// ACCESSOR& accessor,
136/// const char *attributeName,
137/// int attributeNameLength);
138///
139/// /// Invoke the specified `accessor` on the attribute of the specified
140/// /// `object` with the given `attributeId`, supplying `accessor` with the
141/// /// corresponding attribute information structure. The supplied `accessor`
142/// /// must be a callable type that can be called as if it had the following
143/// /// signature:
144/// /// ```
145/// /// template <class t_INFO>
146/// /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
147/// /// ```
148/// /// Return non-zero if the attribute is not found, and the value returned
149/// /// from the invocation of `accessor` otherwise.
150/// template <typename ACCESSOR>
151/// int bdlat_sequenceAccessAttribute(const YOUR_TYPE& object,
152/// ACCESSOR& accessor,
153/// int attributeId);
154///
155/// /// Invoke the specified `accessor` sequentially on each attribute of the
156/// /// specified `object`, supplying `accessor` with the corresponding
157/// /// attribute information structure until such invocation returns a non-zero
158/// /// value. The supplied `accessor` must be a callable type that can be
159/// /// called as if it had the following signature:
160/// /// ```
161/// /// template <class t_INFO>
162/// /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
163/// /// ```
164/// /// Return the value from the last invocation of `accessor` (i.e., the
165/// /// invocation that terminated the sequence).
166/// template <typename ACCESSOR>
167/// int bdlat_sequenceAccessAttributes(const YOUR_TYPE& object,
168/// ACCESSOR& accessor);
169///
170/// /// Return true if the specified `object` has an attribute with the
171/// /// specified `attributeName` of the specified `attributeNameLength`, and
172/// /// false otherwise.
173/// bool bdlat_sequenceHasAttribute(const YOUR_TYPE& object,
174/// const char *attributeName,
175/// int attributeNameLength);
176///
177/// /// Return true if the specified `object` has an attribute with the
178/// /// specified `attributeId`, and false otherwise.
179/// bool bdlat_sequenceHasAttribute(const YOUR_TYPE& object,
180/// int attributeId);
181/// @endcode
182/// Also, the `IsSequence` meta-function must be specialized for the
183/// `mine::MySequence` type in the `bdlat_SequenceFunctions` namespace.
184///
185/// An example of plugging in a user-defined sequence type into the `bdlat`
186/// framework is shown in the @ref bdlat_sequencefunctions-usage section of this document.
187///
188/// ## Usage {#bdlat_sequencefunctions-usage}
189///
190///
191/// This section illustrates intended use of this component.
192///
193/// ### Example 1: Basic Usage {#bdlat_sequencefunctions-example-1-basic-usage}
194///
195///
196/// Suppose you had a `struct` that contains three members:
197/// @code
198/// namespace BloombergLP {
199///
200/// namespace mine {
201///
202/// /// This struct represents a sequence containing a `string` member, an `int`
203/// /// member, and a `float` member.
204/// struct MySequence {
205/// // CONSTANTS
206/// enum {
207/// NAME_ATTRIBUTE_ID = 1,
208/// AGE_ATTRIBUTE_ID = 2,
209/// SALARY_ATTRIBUTE_ID = 3
210/// };
211///
212/// // DATA MEMBERS
213/// bsl::string d_name;
214/// int d_age;
215/// float d_salary;
216/// };
217///
218/// } // close namespace mine
219/// @endcode
220/// We can now make `mine::MySequence` expose "sequence" behavior by
221/// implementing the necessary `bdlat_sequence*` functions for `MySequence`
222/// inside the `mine` namespace. First, we should forward declare all the
223/// functions that we will implement inside the `mine` namespace:
224/// @code
225/// namespace mine {
226///
227/// template <class MANIPULATOR>
228/// int bdlat_sequenceManipulateAttribute(MySequence *object,
229/// MANIPULATOR& manipulator,
230/// const char *attributeName,
231/// int attributeNameLength);
232/// template <class MANIPULATOR>
233/// int bdlat_sequenceManipulateAttribute(MySequence *object,
234/// MANIPULATOR& manipulator,
235/// int attributeId);
236/// template <class MANIPULATOR>
237/// int bdlat_sequenceManipulateAttributes(MySequence *object,
238/// MANIPULATOR& manipulator);
239/// template <class ACCESSOR>
240/// int bdlat_sequenceAccessAttribute(const MySequence& object,
241/// ACCESSOR& accessor,
242/// const char *attributeName,
243/// int attributeNameLength);
244/// template <class ACCESSOR>
245/// int bdlat_sequenceAccessAttribute(const MySequence& object,
246/// ACCESSOR& accessor,
247/// int attributeId);
248/// template <class ACCESSOR>
249/// int bdlat_sequenceAccessAttributes(const MySequence& object,
250/// ACCESSOR& accessor);
251/// bool bdlat_sequenceHasAttribute(const MySequence& object,
252/// const char *attributeName,
253/// int attributeNameLength);
254/// bool bdlat_sequenceHasAttribute(const MySequence& object,
255/// int attributeId);
256///
257/// } // close namespace mine
258/// @endcode
259/// Now, we will implement these functions. Note that for this implementation,
260/// we will create a temporary `bdlat_AttributeInfo` object and pass it along
261/// when invoking the manipulator or accessor. See the @ref bdlat_attributeinfo
262/// component-level documentation for more information. The implementation of
263/// the functions are as follows:
264/// @code
265/// template <class MANIPULATOR>
266/// int mine::bdlat_sequenceManipulateAttribute(
267/// MySequence *object,
268/// MANIPULATOR& manipulator,
269/// const char *attributeName,
270/// int attributeNameLength)
271/// {
272/// enum { NOT_FOUND = -1 };
273///
274/// if (bdlb::String::areEqualCaseless("name",
275/// attributeName,
276/// attributeNameLength)) {
277/// return bdlat_sequenceManipulateAttribute(
278/// object,
279/// manipulator,
280/// MySequence::NAME_ATTRIBUTE_ID);
281/// // RETURN
282/// }
283///
284/// if (bdlb::String::areEqualCaseless("age",
285/// attributeName,
286/// attributeNameLength)) {
287/// return bdlat_sequenceManipulateAttribute(
288/// object,
289/// manipulator,
290/// MySequence::AGE_ATTRIBUTE_ID);
291/// // RETURN
292/// }
293///
294/// if (bdlb::String::areEqualCaseless("salary",
295/// attributeName,
296/// attributeNameLength)) {
297/// return bdlat_sequenceManipulateAttribute(
298/// object,
299/// manipulator,
300/// MySequence::SALARY_ATTRIBUTE_ID);
301/// // RETURN
302/// }
303///
304/// return NOT_FOUND;
305/// }
306///
307/// template <class MANIPULATOR>
308/// int mine::bdlat_sequenceManipulateAttribute(MySequence *object,
309/// MANIPULATOR& manipulator,
310/// int attributeId)
311/// {
312/// enum { NOT_FOUND = -1 };
313///
314/// switch (attributeId) {
315/// case MySequence::NAME_ATTRIBUTE_ID: {
316/// bdlat_AttributeInfo info;
317///
318/// info.annotation() = "Name of employee";
319/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
320/// info.id() = MySequence::NAME_ATTRIBUTE_ID;
321/// info.name() = "name";
322/// info.nameLength() = 4;
323///
324/// return manipulator(&object->d_name, info); // RETURN
325/// }
326/// case MySequence::AGE_ATTRIBUTE_ID: {
327/// bdlat_AttributeInfo info;
328///
329/// info.annotation() = "Age of employee";
330/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
331/// info.id() = MySequence::AGE_ATTRIBUTE_ID;
332/// info.name() = "age";
333/// info.nameLength() = 3;
334///
335/// return manipulator(&object->d_age, info); // RETURN
336/// }
337/// case MySequence::SALARY_ATTRIBUTE_ID: {
338/// bdlat_AttributeInfo info;
339///
340/// info.annotation() = "Salary of employee";
341/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
342/// info.id() = MySequence::SALARY_ATTRIBUTE_ID;
343/// info.name() = "salary";
344/// info.nameLength() = 6;
345///
346/// return manipulator(&object->d_salary, info); // RETURN
347/// }
348/// default: {
349/// return NOT_FOUND; // RETURN
350/// }
351/// }
352/// }
353///
354/// template <class MANIPULATOR>
355/// int mine::bdlat_sequenceManipulateAttributes(MySequence *object,
356/// MANIPULATOR& manipulator)
357/// {
358/// int retVal;
359///
360/// retVal = bdlat_sequenceManipulateAttribute(
361/// object,
362/// manipulator,
363/// MySequence::NAME_ATTRIBUTE_ID);
364///
365/// if (0 != retVal) {
366/// return retVal; // RETURN
367/// }
368///
369/// retVal = bdlat_sequenceManipulateAttribute(
370/// object,
371/// manipulator,
372/// MySequence::AGE_ATTRIBUTE_ID);
373///
374/// if (0 != retVal) {
375/// return retVal; // RETURN
376/// }
377///
378/// retVal = bdlat_sequenceManipulateAttribute(
379/// object,
380/// manipulator,
381/// MySequence::SALARY_ATTRIBUTE_ID);
382///
383/// return retVal;
384/// }
385///
386/// // ACCESSORS
387///
388/// template <class ACCESSOR>
389/// int mine::bdlat_sequenceAccessAttribute(
390/// const MySequence& object,
391/// ACCESSOR& accessor,
392/// const char *attributeName,
393/// int attributeNameLength)
394/// {
395/// enum { NOT_FOUND = -1 };
396///
397/// if (bdlb::String::areEqualCaseless("name",
398/// attributeName,
399/// attributeNameLength)) {
400/// return bdlat_sequenceAccessAttribute(
401/// object,
402/// accessor,
403/// MySequence::NAME_ATTRIBUTE_ID);
404/// // RETURN
405/// }
406///
407/// if (bdlb::String::areEqualCaseless("age",
408/// attributeName,
409/// attributeNameLength)) {
410/// return bdlat_sequenceAccessAttribute(object,
411/// accessor,
412/// MySequence::AGE_ATTRIBUTE_ID);
413/// // RETURN
414/// }
415///
416/// if (bdlb::String::areEqualCaseless("salary",
417/// attributeName,
418/// attributeNameLength)) {
419/// return bdlat_sequenceAccessAttribute(
420/// object,
421/// accessor,
422/// MySequence::SALARY_ATTRIBUTE_ID);
423/// // RETURN
424/// }
425///
426/// return NOT_FOUND;
427/// }
428///
429/// template <class ACCESSOR>
430/// int mine::bdlat_sequenceAccessAttribute(const MySequence& object,
431/// ACCESSOR& accessor,
432/// int attributeId)
433/// {
434/// enum { NOT_FOUND = -1 };
435///
436/// switch (attributeId) {
437/// case MySequence::NAME_ATTRIBUTE_ID: {
438/// bdlat_AttributeInfo info;
439///
440/// info.annotation() = "Name of employee";
441/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
442/// info.id() = MySequence::NAME_ATTRIBUTE_ID;
443/// info.name() = "name";
444/// info.nameLength() = 4;
445///
446/// return accessor(object.d_name, info); // RETURN
447/// }
448/// case MySequence::AGE_ATTRIBUTE_ID: {
449/// bdlat_AttributeInfo info;
450///
451/// info.annotation() = "Age of employee";
452/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
453/// info.id() = MySequence::AGE_ATTRIBUTE_ID;
454/// info.name() = "age";
455/// info.nameLength() = 3;
456///
457/// return accessor(object.d_age, info); // RETURN
458/// }
459/// case MySequence::SALARY_ATTRIBUTE_ID: {
460/// bdlat_AttributeInfo info;
461///
462/// info.annotation() = "Salary of employee";
463/// info.formattingMode() = bdlat_FormattingMode::e_DEFAULT;
464/// info.id() = MySequence::SALARY_ATTRIBUTE_ID;
465/// info.name() = "salary";
466/// info.nameLength() = 6;
467///
468/// return accessor(object.d_salary, info); // RETURN
469/// }
470/// default: {
471/// return NOT_FOUND; // RETURN
472/// }
473/// }
474/// }
475///
476/// template <class ACCESSOR>
477/// int mine::bdlat_sequenceAccessAttributes(const MySequence& object,
478/// ACCESSOR& accessor)
479/// {
480/// int retVal;
481///
482/// retVal = bdlat_sequenceAccessAttribute(object,
483/// accessor,
484/// MySequence::NAME_ATTRIBUTE_ID);
485///
486/// if (0 != retVal) {
487/// return retVal; // RETURN
488/// }
489///
490/// retVal = bdlat_sequenceAccessAttribute(object,
491/// accessor,
492/// MySequence::AGE_ATTRIBUTE_ID);
493///
494/// if (0 != retVal) {
495/// return retVal; // RETURN
496/// }
497///
498/// retVal = bdlat_sequenceAccessAttribute(
499/// object,
500/// accessor,
501/// MySequence::SALARY_ATTRIBUTE_ID);
502///
503/// return retVal;
504/// }
505///
506/// bool mine::bdlat_sequenceHasAttribute(
507/// const MySequence& ,
508/// const char *attributeName,
509/// int attributeNameLength)
510/// {
511/// return bdlb::String::areEqualCaseless("name",
512/// attributeName,
513/// attributeNameLength)
514/// || bdlb::String::areEqualCaseless("age",
515/// attributeName,
516/// attributeNameLength)
517/// || bdlb::String::areEqualCaseless("salary",
518/// attributeName,
519/// attributeNameLength);
520/// }
521///
522/// bool mine::bdlat_sequenceHasAttribute(const MySequence& , int attributeId)
523/// {
524/// return MySequence::NAME_ATTRIBUTE_ID == attributeId
525/// || MySequence::AGE_ATTRIBUTE_ID == attributeId
526/// || MySequence::SALARY_ATTRIBUTE_ID == attributeId;
527/// }
528/// @endcode
529/// Finally, we need to specialize the `IsSequence` meta-function in the
530/// `bdlat_SequenceFunctions` namespace for the `mine::MySequence` type. This
531/// makes the `bdlat` infrastructure recognize `mine::MySequence` as a sequence
532/// abstraction:
533/// @code
534/// namespace bdlat_SequenceFunctions {
535///
536/// template <>
537/// struct IsSequence<mine::MySequence> : bsl::true_type {
538/// };
539///
540/// } // close namespace bdlat_SequenceFunctions
541/// } // close enterprise namespace
542/// @endcode
543/// The `bdlat` infrastructure (and any component that uses this infrastructure)
544/// will now recognize `mine::MySequence` as a "sequence" type. For example,
545/// suppose we have the following XML data:
546/// @code
547/// <?xml version='1.0' encoding='UTF-8' ?>
548/// <MySequence>
549/// <name>John Doe</name>
550/// <age>29</age>
551/// <salary>12345.00</salary>
552/// </MySequence>
553/// @endcode
554/// Using the @ref balxml_decoder component, we can now load this XML data into a
555/// `mine::MySequence` object:
556/// @code
557/// #include <balxml_decoder.h>
558///
559/// void decodeMySequenceFromXML(bsl::istream& inputData)
560/// {
561/// mine::MySequence object;
562///
563/// balxml::DecoderOptions options;
564/// balxml::MiniReader reader;
565/// balxml::ErrorInfo errInfo;
566///
567/// balxml::Decoder decoder(&options, &reader, &errInfo);
568/// int result = decoder.decode(inputData, &object);
569///
570/// assert(0 == result);
571/// assert("John Doe" == object.d_name);
572/// assert(29 == object.d_age);
573/// assert(12345.00 == object.d_salary);
574/// }
575/// @endcode
576/// Note that the `bdlat` framework can be used for functionality other than
577/// encoding/decoding into XML. When `mine::MySequence` is plugged into the
578/// framework, then it will be automatically usable within the framework. For
579/// example, the following snippets of code will print out all the attributes of
580/// a sequence object:
581/// @code
582/// /// Print each visited object to the bound `d_stream_p` object.
583/// struct PrintAttribute {
584/// // DATA MEMBERS
585/// bsl::ostream *d_stream_p;
586///
587/// template <class TYPE, class INFO>
588/// int operator()(const TYPE& object, const INFO& info)
589/// {
590/// (*d_stream_p) << info.name() << ": " << object << bsl::endl;
591/// return 0;
592/// }
593/// };
594///
595/// template <class TYPE>
596/// void printSequenceAttributes(bsl::ostream& stream, const TYPE& object)
597/// {
598/// PrintAttribute accessor;
599/// accessor.d_stream_p = &stream;
600///
601/// bdlat_SequenceFunctions::accessAttributes(object, accessor);
602/// }
603/// @endcode
604/// Now we have a generic function that takes an output stream and a sequence
605/// object, and prints out each attribute with its name and value. We can use
606/// this generic function as follows:
607/// @code
608/// void printMySequence(bsl::ostream& stream)
609/// {
610/// mine::MySequence object;
611///
612/// object.d_name = "John Doe";
613/// object.d_age = 25;
614/// object.d_salary = 12345.00;
615///
616/// stream << bsl::fixed << bsl::setprecision(2);
617///
618/// printSequenceAttributes(stream, object);
619/// }
620/// @endcode
621/// The function above will print the following to provided stream:
622/// @code
623/// name: John Doe
624/// age: 25
625/// salary: 12345.00
626/// @endcode
627/// @}
628/** @} */
629/** @} */
630
631/** @addtogroup bdl
632 * @{
633 */
634/** @addtogroup bdlat
635 * @{
636 */
637/** @addtogroup bdlat_sequencefunctions
638 * @{
639 */
640
641#include <bdlscm_version.h>
642
643#include <bdlat_bdeatoverrides.h>
644#include <bdlat_typetraits.h>
645
646#include <bslalg_hastrait.h>
647
648#include <bslmf_assert.h>
650#include <bslmf_matchanytype.h>
651
652#include <bsls_assert.h>
653#include <bsls_platform.h>
654
655
656
657 // =================================
658 // namespace bdlat_SequenceFunctions
659 // =================================
660
661/// This `namespace` provides methods that expose "sequence" behavior for
662/// "sequence" types. See the component-level documentation for more
663/// information.
664namespace bdlat_SequenceFunctions {
665 // META-FUNCTIONS
666
667 /// This `struct` should be specialized for third-party types that need
668 /// to expose "sequence" behavior. See the component-level
669 /// documentation for further information.
670 template <class TYPE>
672 : public bsl::integral_constant<
673 bool,
674 bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::value> {
675 };
676
677 // MANIPULATORS
678
679 /// Invoke the specified `manipulator` on the address of the (modifiable)
680 /// attribute indicated by the specified `attributeName` and
681 /// `attributeNameLength` of the specified `object`, supplying
682 /// `manipulator` with the corresponding attribute information structure.
683 /// The supplied `manipulator` must be a callable type that can be called
684 /// as if it had the following signature:
685 /// @code
686 /// template <class t_INFO>
687 /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
688 /// @endcode
689 /// Return non-zero value if the attribute is not found, and the value
690 /// returned from the invocation of `manipulator` otherwise.
691 template <class TYPE, class MANIPULATOR>
692 int manipulateAttribute(TYPE *object,
693 MANIPULATOR& manipulator,
694 const char *attributeName,
695 int attributeNameLength);
696
697 /// Invoke the specified `manipulator` on the address of the (modifiable)
698 /// attribute indicated by the specified `attributeId` of the specified
699 /// `object`, supplying `manipulator` with the corresponding attribute
700 /// information structure. The supplied `manipulator` must be a callable
701 /// type that can be called as if it had the following signature:
702 /// @code
703 /// template <class t_INFO>
704 /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
705 /// @endcode
706 /// Return non-zero value if the attribute is not found, and the value
707 /// returned from the invocation of `manipulator` otherwise.
708 template <class TYPE, class MANIPULATOR>
709 int manipulateAttribute(TYPE *object,
710 MANIPULATOR& manipulator,
711 int attributeId);
712
713 /// Invoke the specified `manipulator` sequentially on the address of each
714 /// (modifiable) attribute of the specified `object`, supplying
715 /// `manipulator` with the corresponding attribute information structure
716 /// until such invocation returns non-zero value. The supplied
717 /// `manipulator` must be a callable type that can be called as if it had
718 /// the following signature:
719 /// @code
720 /// template <class t_INFO>
721 /// int manipulator(ATTRIBUTE_TYPE *attribute, const t_INFO& info);
722 /// @endcode
723 /// Return the value from the last invocation of `manipulator` (i.e., the
724 /// invocation that terminated the sequence).
725 template <class TYPE, class MANIPULATOR>
726 int manipulateAttributes(TYPE *object, MANIPULATOR& manipulator);
727
728 // ACCESSORS
729
730 /// Invoke the specified `accessor` on the (non-modifiable) attribute of
731 /// the specified `object` indicated by the specified `attributeName` and
732 /// `attributeNameLength`, supplying `accessor` with the corresponding
733 /// attribute information structure. The supplied `accessor` must be a
734 /// callable type that can be called as if it had the following signature:
735 /// @code
736 /// template <class t_INFO>
737 /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
738 /// @endcode
739 /// Return non-zero value if the attribute is not found, and the value
740 /// returned from the invocation of `accessor` otherwise.
741 template <class TYPE, class ACCESSOR>
742 int accessAttribute(const TYPE& object,
743 ACCESSOR& accessor,
744 const char *attributeName,
745 int attributeNameLength);
746
747 /// Invoke the specified `accessor` on the attribute of the specified
748 /// `object` with the given `attributeId`, supplying `accessor` with the
749 /// corresponding attribute information structure. The supplied `accessor`
750 /// must be a callable type that can be called as if it had the following
751 /// signature:
752 /// @code
753 /// template <class t_INFO>
754 /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
755 /// @endcode
756 /// Return non-zero if the attribute is not found, and the value returned
757 /// from the invocation of `accessor` otherwise.
758 template <class TYPE, class ACCESSOR>
759 int accessAttribute(const TYPE& object,
760 ACCESSOR& accessor,
761 int attributeId);
762
763 /// Invoke the specified `accessor` sequentially on each attribute of
764 /// the specified `object`, supplying `accessor` with the corresponding
765 /// attribute information structure until such invocation returns a
766 /// non-zero value. The supplied `accessor` must be a callable type that
767 /// can be called as if it had the following signature:
768 /// @code
769 /// template <class t_INFO>
770 /// int accessor(const ATTRIBUTE_TYPE& attribute, const t_INFO& info);
771 /// @endcode
772 /// Return the value from the last invocation of `accessor` (i.e., the
773 /// invocation that terminated the sequence).
774 template <class TYPE, class ACCESSOR>
775 int accessAttributes(const TYPE& object, ACCESSOR& accessor);
776
777 /// Return true if the specified `object` has an attribute with the
778 /// specified `attributeName` of the specified `attributeNameLength`,
779 /// and false otherwise.
780 template <class TYPE>
781 bool hasAttribute(const TYPE& object,
782 const char *attributeName,
783 int attributeNameLength);
784
785 /// Return true if the specified `object` has an attribute with the
786 /// specified `attributeId`, and false otherwise.
787 template <class TYPE>
788 bool hasAttribute(const TYPE& object, int attributeId);
789
790} // close namespace bdlat_SequenceFunctions
791
792 // ====================
793 // default declarations
794 // ====================
795
796/// This namespace declaration adds the default implementations of the
797/// "sequence" customization-point functions to `bdlat_SequenceFunctions`.
798/// These default implementations assume the type of the acted-upon object is a
799/// basic-sequence type. For more information about basic-sequence types, see
800/// @ref bdlat_typetraits .
801namespace bdlat_SequenceFunctions {
802 // MANIPULATORS
803 template <class TYPE, class MANIPULATOR>
805 MANIPULATOR& manipulator,
806 const char *attributeName,
807 int attributeNameLength);
808
809 template <class TYPE, class MANIPULATOR>
811 MANIPULATOR& manipulator,
812 int attributeId);
813
814 template <class TYPE, class MANIPULATOR>
816 MANIPULATOR& manipulator);
817
818 // ACCESSORS
819 template <class TYPE, class ACCESSOR>
820 int bdlat_sequenceAccessAttribute(const TYPE& object,
821 ACCESSOR& accessor,
822 const char *attributeName,
823 int attributeNameLength);
824
825 template <class TYPE, class ACCESSOR>
826 int bdlat_sequenceAccessAttribute(const TYPE& object,
827 ACCESSOR& accessor,
828 int attributeId);
829
830 template <class TYPE, class ACCESSOR>
831 int bdlat_sequenceAccessAttributes(const TYPE& object, ACCESSOR& accessor);
832
833 template <class TYPE>
834 bool bdlat_sequenceHasAttribute(const TYPE& object,
835 const char *attributeName,
836 int attributeNameLength);
837
838 template <class TYPE>
839 bool bdlat_sequenceHasAttribute(const TYPE& object,
840 int attributeId);
841
842} // close namespace bdlat_SequenceFunctions
843
844// ============================================================================
845// INLINE FUNCTION DEFINITIONS
846// ============================================================================
847
848 // ---------------------------------
849 // namespace bdlat_SequenceFunctions
850 // ---------------------------------
851
852// MANIPULATORS
853template <class TYPE, class MANIPULATOR>
854inline
856 TYPE *object,
857 MANIPULATOR& manipulator,
858 const char *attributeName,
859 int attributeNameLength)
860{
861 return bdlat_sequenceManipulateAttribute(object,
862 manipulator,
863 attributeName,
864 attributeNameLength);
865}
866
867template <class TYPE, class MANIPULATOR>
868inline
870 MANIPULATOR& manipulator,
871 int attributeId)
872{
873 return bdlat_sequenceManipulateAttribute(object, manipulator, attributeId);
874}
875
876template <class TYPE, class MANIPULATOR>
877inline
879 MANIPULATOR& manipulator)
880{
881 return bdlat_sequenceManipulateAttributes(object, manipulator);
882}
883
884// ACCESSORS
885template <class TYPE, class ACCESSOR>
886inline
887int bdlat_SequenceFunctions::accessAttribute(const TYPE& object,
888 ACCESSOR& accessor,
889 const char *attributeName,
890 int attributeNameLength)
891{
892 return bdlat_sequenceAccessAttribute(object,
893 accessor,
894 attributeName,
895 attributeNameLength);
896}
897
898template <class TYPE, class ACCESSOR>
899inline
900int bdlat_SequenceFunctions::accessAttribute(const TYPE& object,
901 ACCESSOR& accessor,
902 int attributeId)
903{
904 return bdlat_sequenceAccessAttribute(object, accessor, attributeId);
905}
906
907template <class TYPE, class ACCESSOR>
908inline
909int bdlat_SequenceFunctions::accessAttributes(const TYPE& object,
910 ACCESSOR& accessor)
911{
912 return bdlat_sequenceAccessAttributes(object, accessor);
913}
914
915template <class TYPE>
916inline
917bool bdlat_SequenceFunctions::hasAttribute(const TYPE& object,
918 const char *attributeName,
919 int attributeNameLength)
920{
921 return bdlat_sequenceHasAttribute(object,
922 attributeName,
923 attributeNameLength);
924}
925
926template <class TYPE>
927inline
928bool bdlat_SequenceFunctions::hasAttribute(const TYPE& object,
929 int attributeId)
930{
931 return bdlat_sequenceHasAttribute(object, attributeId);
932}
933
934
935 // -------------------
936 // default definitions
937 // -------------------
938
939// MANIPULATORS
940template <class TYPE, class MANIPULATOR>
941inline
943 TYPE *object,
944 MANIPULATOR& manipulator,
945 const char *attributeName,
946 int attributeNameLength)
947{
950
951 return object->manipulateAttribute(manipulator,
952 attributeName,
953 attributeNameLength);
954}
955
956template <class TYPE, class MANIPULATOR>
957inline
959 TYPE *object,
960 MANIPULATOR& manipulator,
961 int attributeId)
962{
965
966 return object->manipulateAttribute(manipulator, attributeId);
967}
968
969template <class TYPE, class MANIPULATOR>
970inline
972 TYPE *object,
973 MANIPULATOR& manipulator)
974{
977
978 return object->manipulateAttributes(manipulator);
979}
980
981// ACCESSORS
982template <class TYPE, class ACCESSOR>
983inline
985 const TYPE& object,
986 ACCESSOR& accessor,
987 const char *attributeName,
988 int attributeNameLength)
989{
992
993 return object.accessAttribute(accessor,
994 attributeName,
995 attributeNameLength);
996}
997
998template <class TYPE, class ACCESSOR>
999inline
1001 const TYPE& object,
1002 ACCESSOR& accessor,
1003 int attributeId)
1004{
1007
1008 return object.accessAttribute(accessor, attributeId);
1009}
1010
1011template <class TYPE, class ACCESSOR>
1012inline
1014 const TYPE& object,
1015 ACCESSOR& accessor)
1016{
1019
1020 return object.accessAttributes(accessor);
1021}
1022
1023template <class TYPE>
1024inline
1026 const TYPE& object,
1027 const char *attributeName,
1028 int attributeNameLength)
1029{
1032
1033 return 0 != object.lookupAttributeInfo(attributeName, attributeNameLength);
1034}
1035
1036template <class TYPE>
1037inline
1039 const TYPE& object,
1040 int attributeId)
1041{
1044
1045 return 0 != object.lookupAttributeInfo(attributeId);
1046}
1047
1048
1049
1050#endif
1051
1052// ----------------------------------------------------------------------------
1053// Copyright 2015 Bloomberg Finance L.P.
1054//
1055// Licensed under the Apache License, Version 2.0 (the "License");
1056// you may not use this file except in compliance with the License.
1057// You may obtain a copy of the License at
1058//
1059// http://www.apache.org/licenses/LICENSE-2.0
1060//
1061// Unless required by applicable law or agreed to in writing, software
1062// distributed under the License is distributed on an "AS IS" BASIS,
1063// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1064// See the License for the specific language governing permissions and
1065// limitations under the License.
1066// ----------------------------- END-OF-FILE ----------------------------------
1067
1068/** @} */
1069/** @} */
1070/** @} */
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
bool bdlat_sequenceHasAttribute(const SequenceRef &ref, const char *attributeName, int attributeNameLength)
Definition bdlar_sequenceref.h:487
int bdlat_sequenceAccessAttribute(const SequenceRef &ref, t_ACCESSOR &accessor, const char *attributeName, int attributeNameLength)
Definition bdlar_sequenceref.h:461
int bdlat_sequenceManipulateAttributes(SequenceRef *ref, t_MANIPULATOR &manipulator)
Definition bdlar_sequenceref.h:453
int bdlat_sequenceManipulateAttribute(SequenceRef *ref, t_MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
Definition bdlar_sequenceref.h:432
int bdlat_sequenceAccessAttributes(const SequenceRef &ref, t_ACCESSOR &accessor)
Definition bdlar_sequenceref.h:480
Definition bdlar_sequenceref.h:657
bool bdlat_sequenceHasAttribute(const TYPE &object, const char *attributeName, int attributeNameLength)
int bdlat_sequenceAccessAttribute(const TYPE &object, ACCESSOR &accessor, const char *attributeName, int attributeNameLength)
int accessAttribute(const TYPE &object, ACCESSOR &accessor, const char *attributeName, int attributeNameLength)
int accessAttributes(const TYPE &object, ACCESSOR &accessor)
int manipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
int manipulateAttributes(TYPE *object, MANIPULATOR &manipulator)
bool hasAttribute(const TYPE &object, const char *attributeName, int attributeNameLength)
int bdlat_sequenceAccessAttributes(const TYPE &object, ACCESSOR &accessor)
int bdlat_sequenceManipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
int bdlat_sequenceManipulateAttributes(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_sequencefunctions.h:674
Definition bslmf_integralconstant.h:261
Definition bslalg_hastrait.h:117