// bdlat_sequencefunctions.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BDLAT_SEQUENCEFUNCTIONS #define INCLUDED_BDLAT_SEQUENCEFUNCTIONS #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a namespace defining sequence functions. // //@CLASSES: // bdlat_SequenceFunctions: namespace for calling sequence functions // //@SEE_ALSO: bdlat_attributeinfo // //@DESCRIPTION: The 'bdlat_SequenceFunctions' 'namespace' provided in this // component defines parameterized functions that expose "sequence" behavior // for "sequence" types. See the {'bdlat'} package-level documentation for a // full description of "sequence" types. // // The functions in this namespace allow users to: //: o manipulate an attribute by attribute id or attribute name using a //: parameterized manipulator ('manipulateAttribute'), //: o manipulate all attributes sequentially using a parameterized manipulator //: ('manipulateAttributes'), //: o access an attribute by attribute id or attribute name using a //: parameterized accessor ('accessAttribute'), and //: o access all attributes sequentially using a parameterized accessor //: ('accessAttributes'). // // Also, the meta-function 'IsSequence' contains a compile-time constant // 'VALUE' that is non-zero if the parameterized 'TYPE' exposes "sequence" // behavior through the 'bdlat_SequenceFunctions' 'namespace'. // // This component specializes all of these functions for types that have the // 'bdlat_TypeTraitBasicSequence' trait. // // Types that do not have the 'bdlat_TypeTraitBasicSequence' trait can be // plugged into the 'bdlat' framework. This is done by overloading the // 'bdlat_sequence*' functions inside the namespace of the plugged in type. // For example, suppose there is a type called 'mine::MySequence'. In order to // plug this type into the 'bdlat' framework as a "sequence", the following // functions must be declared and implemented in the 'mine' namespace: //.. // namespace mine { // // // MANIPULATORS // template <typename MANIPULATOR> // int bdlat_sequenceManipulateAttribute( // MySequence *object, // MANIPULATOR& manipulator, // const char *attributeName, // int attributeNameLength); // // Invoke the specified 'manipulator' on the address of the // // (modifiable) attribute indicated by the specified 'attributeName' // // and 'attributeNameLength' of the specified 'object', supplying // // 'manipulator' with the corresponding attribute information // // structure. Return non-zero value if the attribute is not found, and // // the value returned from the invocation of 'manipulator' otherwise. // // template <typename MANIPULATOR> // int bdlat_sequenceManipulateAttribute(MySequence *object, // MANIPULATOR& manipulator, // int attributeId); // // Invoke the specified 'manipulator' on the address of the // // (modifiable) attribute indicated by the specified 'attributeId' of // // the specified 'object', supplying 'manipulator' with the // // corresponding attribute information structure. Return non-zero // // value if the attribute is not found, and the value returned from the // // invocation of 'manipulator' otherwise. // // template <typename MANIPULATOR> // int bdlat_sequenceManipulateAttributes(MySequence *object, // MANIPULATOR& manipulator); // // Invoke the specified 'manipulator' sequentially on the address of // // each (modifiable) attribute of the specified 'object', supplying // // 'manipulator' with the corresponding attribute information structure // // until such invocation returns non-zero value. Return the value from // // the last invocation of 'manipulator' (i.e., the invocation that // // terminated the sequence). // // // ACCESSORS // template <typename ACCESSOR> // int bdlat_sequenceAccessAttribute(const MySequence& object, // ACCESSOR& accessor, // const char *attributeName, // int attributeNameLength); // // Invoke the specified 'accessor' on the (non-modifiable) attribute of // // the specified 'object' indicated by the specified 'attributeName' // // and 'attributeNameLength', supplying 'accessor' with the // // corresponding attribute information structure. Return non-zero // // value if the attribute is not found, and the value returned from the // // invocation of 'accessor' otherwise. // // template <typename ACCESSOR> // int bdlat_sequenceAccessAttribute(const MySequence& object, // ACCESSOR& accessor, // int attributeId); // // Invoke the specified 'accessor' on the attribute of the specified // // 'object' with the given 'attributeId', supplying 'accessor' with the // // corresponding attribute information structure. Return non-zero if // // the attribute is not found, and the value returned from the // // invocation of 'accessor' otherwise. // // template <typename ACCESSOR> // int bdlat_sequenceAccessAttributes(const MySequence& object, // ACCESSOR& accessor); // // Invoke the specified 'accessor' sequentially on each attribute of // // the specified 'object', supplying 'accessor' with the corresponding // // attribute information structure until such invocation returns a // // non-zero value. Return the value from the last invocation of // // 'accessor' (i.e., the invocation that terminated the sequence). // // bool bdlat_sequenceHasAttribute(const MySequence& object, // const char *attributeName, // int attributeNameLength); // // Return true if the specified 'object' has an attribute with the // // specified 'attributeName' of the specified 'attributeNameLength', // // and false otherwise. // // bool bdlat_sequenceHasAttribute(const MySequence& object, // int attributeId); // // Return true if the specified 'object' has an attribute with the // // specified 'attributeId', and false otherwise. // // } // close namespace 'mine' //.. // Also, the 'IsSequence' meta-function must be specialized for the // 'mine::MySequence' type in the 'bdlat_SequenceFunctions' namespace. // // An example of plugging in a user-defined sequence type into the 'bdlat' // framework is shown in the {'Usage'} section of this document. // ///Usage ///----- // The following snippets of code illustrate the usage of this component. // Suppose you had a 'struct' that contains three members: //.. // // namespace BloombergLP { // // namespace mine { // // struct MySequence { // // This struct represents a sequence containing a 'string' member, an // // 'int' member, and a 'float' member. // // // CONSTANTS // enum { // NAME_ATTRIBUTE_ID = 1, // AGE_ATTRIBUTE_ID = 2, // SALARY_ATTRIBUTE_ID = 3 // }; // // // DATA MEMBERS // bsl::string d_name; // int d_age; // float d_salary; // }; // // } // close namespace mine //.. // We can now make 'mine::MySequence' expose "sequence" behavior by // implementing the necessary 'bdlat_sequence*' functions for 'MySequence' // inside the 'mine' namespace. First, we should forward declare all the // functions that we will implement inside the 'mine' namespace: //.. // namespace mine { // // template <class MANIPULATOR> // int bdlat_sequenceManipulateAttribute(MySequence *object, // MANIPULATOR& manipulator, // const char *attributeName, // int attributeNameLength); // template <class MANIPULATOR> // int bdlat_sequenceManipulateAttribute(MySequence *object, // MANIPULATOR& manipulator, // int attributeId); // template <class MANIPULATOR> // int bdlat_sequenceManipulateAttributes(MySequence *object, // MANIPULATOR& manipulator); // template <class ACCESSOR> // int bdlat_sequenceAccessAttribute(const MySequence& object, // ACCESSOR& accessor, // const char *attributeName, // int attributeNameLength); // template <class ACCESSOR> // int bdlat_sequenceAccessAttribute(const MySequence& object, // ACCESSOR& accessor, // int attributeId); // template <class ACCESSOR> // int bdlat_sequenceAccessAttributes(const MySequence& object, // ACCESSOR& accessor); // bool bdlat_sequenceHasAttribute(const MySequence& object, // const char *attributeName, // int attributeNameLength); // bool bdlat_sequenceHasAttribute(const MySequence& object, // int attributeId); // // } // close namespace mine //.. // Now, we will implement these functions. Note that for this implementation, // we will create a temporary 'bdlat_AttributeInfo' object and pass it along // when invoking the manipulator or accessor. See the {'bdlat_attributeinfo'} // component-level documentation for more information. The implementation of // the functions are as follows: //.. // template <class MANIPULATOR> // int mine::bdlat_sequenceManipulateAttribute( // MySequence *object, // MANIPULATOR& manipulator, // const char *attributeName, // int attributeNameLength) // { // enum { NOT_FOUND = -1 }; // // if (bdlb::String::areEqualCaseless("name", // attributeName, // attributeNameLength)) { // return bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::NAME_ATTRIBUTE_ID); // // RETURN // } // // if (bdlb::String::areEqualCaseless("age", // attributeName, // attributeNameLength)) { // return bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::AGE_ATTRIBUTE_ID); // // RETURN // } // // if (bdlb::String::areEqualCaseless("salary", // attributeName, // attributeNameLength)) { // return bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::SALARY_ATTRIBUTE_ID); // // RETURN // } // // return NOT_FOUND; // } // // template <class MANIPULATOR> // int mine::bdlat_sequenceManipulateAttribute(MySequence *object, // MANIPULATOR& manipulator, // int attributeId) // { // enum { NOT_FOUND = -1 }; // // switch (attributeId) { // case MySequence::NAME_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Name of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::NAME_ATTRIBUTE_ID; // info.name() = "name"; // info.nameLength() = 4; // // return manipulator(&object->d_name, info); // RETURN // } // case MySequence::AGE_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Age of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::AGE_ATTRIBUTE_ID; // info.name() = "age"; // info.nameLength() = 3; // // return manipulator(&object->d_age, info); // RETURN // } // case MySequence::SALARY_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Salary of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::SALARY_ATTRIBUTE_ID; // info.name() = "salary"; // info.nameLength() = 6; // // return manipulator(&object->d_salary, info); // RETURN // } // default: { // return NOT_FOUND; // RETURN // } // } // } // // template <class MANIPULATOR> // int mine::bdlat_sequenceManipulateAttributes(MySequence *object, // MANIPULATOR& manipulator) // { // int retVal; // // retVal = bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::NAME_ATTRIBUTE_ID); // // if (0 != retVal) { // return retVal; // RETURN // } // // retVal = bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::AGE_ATTRIBUTE_ID); // // if (0 != retVal) { // return retVal; // RETURN // } // // retVal = bdlat_sequenceManipulateAttribute( // object, // manipulator, // MySequence::SALARY_ATTRIBUTE_ID); // // return retVal; // } // // // ACCESSORS // // template <class ACCESSOR> // int mine::bdlat_sequenceAccessAttribute( // const MySequence& object, // ACCESSOR& accessor, // const char *attributeName, // int attributeNameLength) // { // enum { NOT_FOUND = -1 }; // // if (bdlb::String::areEqualCaseless("name", // attributeName, // attributeNameLength)) { // return bdlat_sequenceAccessAttribute( // object, // accessor, // MySequence::NAME_ATTRIBUTE_ID); // // RETURN // } // // if (bdlb::String::areEqualCaseless("age", // attributeName, // attributeNameLength)) { // return bdlat_sequenceAccessAttribute(object, // accessor, // MySequence::AGE_ATTRIBUTE_ID); // // RETURN // } // // if (bdlb::String::areEqualCaseless("salary", // attributeName, // attributeNameLength)) { // return bdlat_sequenceAccessAttribute( // object, // accessor, // MySequence::SALARY_ATTRIBUTE_ID); // // RETURN // } // // return NOT_FOUND; // } // // template <class ACCESSOR> // int mine::bdlat_sequenceAccessAttribute(const MySequence& object, // ACCESSOR& accessor, // int attributeId) // { // enum { NOT_FOUND = -1 }; // // switch (attributeId) { // case MySequence::NAME_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Name of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::NAME_ATTRIBUTE_ID; // info.name() = "name"; // info.nameLength() = 4; // // return accessor(object.d_name, info); // RETURN // } // case MySequence::AGE_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Age of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::AGE_ATTRIBUTE_ID; // info.name() = "age"; // info.nameLength() = 3; // // return accessor(object.d_age, info); // RETURN // } // case MySequence::SALARY_ATTRIBUTE_ID: { // bdlat_AttributeInfo info; // // info.annotation() = "Salary of employee"; // info.formattingMode() = bdlat_FormattingMode::e_DEFAULT; // info.id() = MySequence::SALARY_ATTRIBUTE_ID; // info.name() = "salary"; // info.nameLength() = 6; // // return accessor(object.d_salary, info); // RETURN // } // default: { // return NOT_FOUND; // RETURN // } // } // } // // template <class ACCESSOR> // int mine::bdlat_sequenceAccessAttributes(const MySequence& object, // ACCESSOR& accessor) // { // int retVal; // // retVal = bdlat_sequenceAccessAttribute(object, // accessor, // MySequence::NAME_ATTRIBUTE_ID); // // if (0 != retVal) { // return retVal; // RETURN // } // // retVal = bdlat_sequenceAccessAttribute(object, // accessor, // MySequence::AGE_ATTRIBUTE_ID); // // if (0 != retVal) { // return retVal; // RETURN // } // // retVal = bdlat_sequenceAccessAttribute( // object, // accessor, // MySequence::SALARY_ATTRIBUTE_ID); // // return retVal; // } // // bool mine::bdlat_sequenceHasAttribute( // const MySequence& , // const char *attributeName, // int attributeNameLength) // { // return bdlb::String::areEqualCaseless("name", // attributeName, // attributeNameLength) // || bdlb::String::areEqualCaseless("age", // attributeName, // attributeNameLength) // || bdlb::String::areEqualCaseless("salary", // attributeName, // attributeNameLength); // } // // bool mine::bdlat_sequenceHasAttribute(const MySequence& , int attributeId) // { // return MySequence::NAME_ATTRIBUTE_ID == attributeId // || MySequence::AGE_ATTRIBUTE_ID == attributeId // || MySequence::SALARY_ATTRIBUTE_ID == attributeId; // } //.. // Finally, we need to specialize the 'IsSequence' meta-function in the // 'bdlat_SequenceFunctions' namespace for the 'mine::MySequence' type. This // makes the 'bdlat' infrastructure recognize 'mine::MySequence' as a sequence // abstraction: //.. // namespace bdlat_SequenceFunctions { // // template <> // struct IsSequence<mine::MySequence> { // enum { VALUE = 1 }; // }; // // } // close namespace bdlat_SequenceFunctions // } // close enterprise namespace //.. // The 'bdlat' infrastructure (and any component that uses this infrastructure) // will now recognize 'mine::MySequence' as a "sequence" type. For example, // suppose we have the following XML data: //.. // <?xml version='1.0' encoding='UTF-8' ?> // <MySequence> // <name>John Doe</name> // <age>29</age> // <salary>12345.00</salary> // </MySequence> //.. // Using the 'balxml_decoder' component, we can now load this XML data into a // 'mine::MySequence' object: //.. // #include <balxml_decoder.h> // // void decodeMySequenceFromXML(bsl::istream& inputData) // { // using namespace BloombergLP; // // mine::MySequence object; // // balxml::DecoderOptions options; // balxml::MiniReader reader; // balxml::ErrorInfo errInfo; // // balxml::Decoder decoder(&options, &reader, &errInfo); // int result = decoder.decode(inputData, &object); // // assert(0 == result); // assert("John Doe" == object.d_name); // assert(29 == object.d_age); // assert(12345.00 == object.d_salary); // } //.. // Note that the 'bdlat' framework can be used for functionality other than // encoding/decoding into XML. When 'mine::MySequence' is plugged into the // framework, then it will be automatically usable within the framework. For // example, the following snippets of code will print out all the attributes of // a sequence object: //.. // struct PrintAttribute { // // Print each visited object to the bound 'd_stream_p' object. // // // DATA MEMBERS // bsl::ostream *d_stream_p; // // template <class TYPE, class INFO> // int operator()(const TYPE& object, const INFO& info) // { // (*d_stream_p) << info.name() << ": " << object << bsl::endl; // return 0; // } // }; // // template <class TYPE> // void printSequenceAttributes(bsl::ostream& stream, const TYPE& object) // { // PrintAttribute accessor; // accessor.d_stream_p = &stream; // // bdlat_SequenceFunctions::accessAttributes(object, accessor); // } //.. // Now we have a generic function that takes an output stream and a sequence // object, and prints out each attribute with its name and value. We can use // this generic function as follows: //.. // void printMySequence(bsl::ostream& stream) // { // mine::MySequence object; // // object.d_name = "John Doe"; // object.d_age = 25; // object.d_salary = 12345.00; // // stream << bsl::fixed << bsl::setprecision(2); // // printSequenceAttributes(stream, object); // } //.. // The function above will print the following to provided stream: //.. // name: John Doe // age: 25 // salary: 12345.00 //.. #include <bdlscm_version.h> #include <bdlat_bdeatoverrides.h> #include <bdlat_typetraits.h> #include <bslalg_hastrait.h> #include <bslmf_assert.h> #include <bslmf_matchanytype.h> #include <bslmf_metaint.h> #include <bsls_assert.h> #include <bsls_platform.h> namespace BloombergLP { // ================================= // namespace bdlat_SequenceFunctions // ================================= namespace bdlat_SequenceFunctions { // This 'namespace' provides methods that expose "sequence" behavior for // "sequence" types. See the component-level documentation for more // information. // META-FUNCTIONS template <class TYPE> struct IsSequence { // This 'struct' should be specialized for third-party types that need // to expose "sequence" behavior. See the component-level // documentation for further information. enum { VALUE = bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE }; }; // MANIPULATORS template <class TYPE, class MANIPULATOR> int manipulateAttribute(TYPE *object, MANIPULATOR& manipulator, const char *attributeName, int attributeNameLength); // Invoke the specified 'manipulator' on the address of the // (modifiable) attribute indicated by the specified 'attributeName' // and 'attributeNameLength' of the specified 'object', supplying // 'manipulator' with the corresponding attribute information // structure. Return non-zero value if the attribute is not found, and // the value returned from the invocation of 'manipulator' otherwise. template <class TYPE, class MANIPULATOR> int manipulateAttribute(TYPE *object, MANIPULATOR& manipulator, int attributeId); // Invoke the specified 'manipulator' on the address of the // (modifiable) attribute indicated by the specified 'attributeId' of // the specified 'object', supplying 'manipulator' with the // corresponding attribute information structure. Return non-zero // value if the attribute is not found, and the value returned from the // invocation of 'manipulator' otherwise. template <class TYPE, class MANIPULATOR> int manipulateAttributes(TYPE *object, MANIPULATOR& manipulator); // Invoke the specified 'manipulator' sequentially on the address of // each (modifiable) attribute of the specified 'object', supplying // 'manipulator' with the corresponding attribute information structure // until such invocation returns non-zero value. Return the value // from the last invocation of 'manipulator' (i.e., the invocation that // terminated the sequence). // ACCESSORS template <class TYPE, class ACCESSOR> int accessAttribute(const TYPE& object, ACCESSOR& accessor, const char *attributeName, int attributeNameLength); // Invoke the specified 'accessor' on the (non-modifiable) attribute of // the specified 'object' indicated by the specified 'attributeName' // and 'attributeNameLength', supplying 'accessor' with the // corresponding attribute information structure. Return non-zero // value if the attribute is not found, and the value returned from the // invocation of 'accessor' otherwise. template <class TYPE, class ACCESSOR> int accessAttribute(const TYPE& object, ACCESSOR& accessor, int attributeId); // Invoke the specified 'accessor' on the attribute of the specified // 'object' with the given 'attributeId', supplying 'accessor' with the // corresponding attribute information structure. Return non-zero if // the attribute is not found, and the value returned from the // invocation of 'accessor' otherwise. template <class TYPE, class ACCESSOR> int accessAttributes(const TYPE& object, ACCESSOR& accessor); // Invoke the specified 'accessor' sequentially on each attribute of // the specified 'object', supplying 'accessor' with the corresponding // attribute information structure until such invocation returns a // non-zero value. Return the value from the last invocation of // 'accessor' (i.e., the invocation that terminated the sequence). template <class TYPE> bool hasAttribute(const TYPE& object, const char *attributeName, int attributeNameLength); // Return true if the specified 'object' has an attribute with the // specified 'attributeName' of the specified 'attributeNameLength', // and false otherwise. template <class TYPE> bool hasAttribute(const TYPE& object, int attributeId); // Return true if the specified 'object' has an attribute with the // specified 'attributeId', and false otherwise. } // close namespace bdlat_SequenceFunctions // ==================== // default declarations // ==================== namespace bdlat_SequenceFunctions { // This namespace declaration adds the default implementations of the // "sequence" customization-point functions to 'bdlat_SequenceFunctions'. // These default implementations assume the type of the acted-upon object // is a basic-sequence type. For more information about basic-sequence // types, see {'bdlat_typetraits'}. // MANIPULATORS template <class TYPE, class MANIPULATOR> int bdlat_sequenceManipulateAttribute(TYPE *object, MANIPULATOR& manipulator, const char *attributeName, int attributeNameLength); template <class TYPE, class MANIPULATOR> int bdlat_sequenceManipulateAttribute(TYPE *object, MANIPULATOR& manipulator, int attributeId); template <class TYPE, class MANIPULATOR> int bdlat_sequenceManipulateAttributes(TYPE *object, MANIPULATOR& manipulator); // ACCESSORS template <class TYPE, class ACCESSOR> int bdlat_sequenceAccessAttribute(const TYPE& object, ACCESSOR& accessor, const char *attributeName, int attributeNameLength); template <class TYPE, class ACCESSOR> int bdlat_sequenceAccessAttribute(const TYPE& object, ACCESSOR& accessor, int attributeId); template <class TYPE, class ACCESSOR> int bdlat_sequenceAccessAttributes(const TYPE& object, ACCESSOR& accessor); template <class TYPE> bool bdlat_sequenceHasAttribute(const TYPE& object, const char *attributeName, int attributeNameLength); template <class TYPE> bool bdlat_sequenceHasAttribute(const TYPE& object, int attributeId); } // close namespace bdlat_SequenceFunctions // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // --------------------------------- // namespace bdlat_SequenceFunctions // --------------------------------- // MANIPULATORS template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::manipulateAttribute( TYPE *object, MANIPULATOR& manipulator, const char *attributeName, int attributeNameLength) { return bdlat_sequenceManipulateAttribute(object, manipulator, attributeName, attributeNameLength); } template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::manipulateAttribute(TYPE *object, MANIPULATOR& manipulator, int attributeId) { return bdlat_sequenceManipulateAttribute(object, manipulator, attributeId); } template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::manipulateAttributes(TYPE *object, MANIPULATOR& manipulator) { return bdlat_sequenceManipulateAttributes(object, manipulator); } // ACCESSORS template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::accessAttribute(const TYPE& object, ACCESSOR& accessor, const char *attributeName, int attributeNameLength) { return bdlat_sequenceAccessAttribute(object, accessor, attributeName, attributeNameLength); } template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::accessAttribute(const TYPE& object, ACCESSOR& accessor, int attributeId) { return bdlat_sequenceAccessAttribute(object, accessor, attributeId); } template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::accessAttributes(const TYPE& object, ACCESSOR& accessor) { return bdlat_sequenceAccessAttributes(object, accessor); } template <class TYPE> inline bool bdlat_SequenceFunctions::hasAttribute(const TYPE& object, const char *attributeName, int attributeNameLength) { return bdlat_sequenceHasAttribute(object, attributeName, attributeNameLength); } template <class TYPE> inline bool bdlat_SequenceFunctions::hasAttribute(const TYPE& object, int attributeId) { return bdlat_sequenceHasAttribute(object, attributeId); } // ------------------- // default definitions // ------------------- // MANIPULATORS template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::bdlat_sequenceManipulateAttribute( TYPE *object, MANIPULATOR& manipulator, const char *attributeName, int attributeNameLength) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object->manipulateAttribute(manipulator, attributeName, attributeNameLength); } template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::bdlat_sequenceManipulateAttribute( TYPE *object, MANIPULATOR& manipulator, int attributeId) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object->manipulateAttribute(manipulator, attributeId); } template <class TYPE, class MANIPULATOR> inline int bdlat_SequenceFunctions::bdlat_sequenceManipulateAttributes( TYPE *object, MANIPULATOR& manipulator) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object->manipulateAttributes(manipulator); } // ACCESSORS template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::bdlat_sequenceAccessAttribute( const TYPE& object, ACCESSOR& accessor, const char *attributeName, int attributeNameLength) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object.accessAttribute(accessor, attributeName, attributeNameLength); } template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::bdlat_sequenceAccessAttribute( const TYPE& object, ACCESSOR& accessor, int attributeId) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object.accessAttribute(accessor, attributeId); } template <class TYPE, class ACCESSOR> inline int bdlat_SequenceFunctions::bdlat_sequenceAccessAttributes( const TYPE& object, ACCESSOR& accessor) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return object.accessAttributes(accessor); } template <class TYPE> inline bool bdlat_SequenceFunctions::bdlat_sequenceHasAttribute( const TYPE& object, const char *attributeName, int attributeNameLength) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return 0 != object.lookupAttributeInfo(attributeName, attributeNameLength); } template <class TYPE> inline bool bdlat_SequenceFunctions::bdlat_sequenceHasAttribute( const TYPE& object, int attributeId) { BSLMF_ASSERT( (bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE)); return 0 != object.lookupAttributeInfo(attributeId); } } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------