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