// bdlat_typename.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_TYPENAME #define INCLUDED_BDLAT_TYPENAME #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide string representations for data type names. // //@CLASSES: // bdlat_TypeName: namespace for type-name functions // //@SEE_ALSO: http://www.w3.org/TR/xmlschema-2/#built-in-datatypes // //@DESCRIPTION: This component defines a structure 'bdlat_TypeName' which // provides a namespace for functions returning information about the object // types. Functions in this namespace allow users to get access to three // categories of information: // //: o class name from the metadata associated with the object type //: o generic type name //: o XML/XSD type name, based on object type and formatting mode. // ///Class Name Information ///---------------------- // The template function 'className' returns the object class name from the // metadata associated with given object type. Metadata is available for the // C++ types that have one the following traits: //.. // 'bdlat_TypeTraitBasicChoice' // 'bdlat_TypeTraitBasicSequence' // 'bdlat_TypeTraitBasicCustomizedType' // 'bdlat_TypeTraitBasicEnumeration' //.. // If metadata is not available for the object type, the function 'className' // returns 0 unless the function 'bdlat_TypeName_className' is overloaded by // developer. // ///Overloable Class Name Functions For User Defined Classes ///-------------------------------------------------------- // To provide the custom name for the given user-defined C++ class, the // developer should overload the template function 'bdlat_TypeName_className' // for this type in the namespace where the type is defined. // //WARNING! Do not extend 'bdlat_TypeName_Overloadable' namespace. // ///Generic Type Name Information ///----------------------------- // The template functions 'name' returns the generic type name for the given // object. The generic type name is one of the following: //.. // o predefined name for fundamental types // o class name from 'bdlat_TypeName_className', if such function returns a // non-null value // o name obtained from 'type_info' object provided by C++ runtime, if no // class name is available //.. // ///XSD Type Name Information ///------------------------- // The template functions 'xsdName' returns the XML/XSD type name, based on // the object type and formatting mode. The returned value is one of the // following: //.. // o predefined name for built-in XSD types // o class name from 'bdlat_TypeName_className', if such function returns // a non-null value // o the "anyType" string, if no class name is available //.. // This component also defines the XSD names for the following C++ types and // formatting modes: //.. // C++ Type Formatting Mode XML Name // -------- --------------- -------- // bool DEFAULT/DEC/TEXT boolean // char DEFAULT/DEC byte // char TEXT string // unsigned char DEFAULT/DEC unsignedByte // short DEFAULT/DEC short // short TEXT string // unsigned short DEFAULT/DEC unsignedShort // int DEFAULT/DEC int // unsigned int DEFAULT/DEC unsignedInt // bsls::Types::Int64 DEFAULT/DEC long // bsls::Types::Uint64 DEFAULT/DEC unsignedLong // float DEFAULT float // float DEC decimal // double DEFAULT double // double DEC decimal // bdldflp::Decimal64 DEFAULT Decimal64 // bsl::string DEFAULT/TEXT string // bsl::string BASE64 base64Binary // bsl::string HEX hexBinary // bdlt::Date DEFAULT date // bdlt::DateTz DEFAULT date // bdlt::Datetime DEFAULT dateTime // bdlt::DatetimeTz DEFAULT dateTime // bdlt::Time DEFAULT time // bdlt::TimeTz DEFAULT time // bsl::vector<char> DEFAULT/BASE64 base64Binary // bsl::vector<char> HEX hexBinary // bsl::vector<char> TEXT string // bsl::vector<short> TEXT string //.. // ///Usage ///----- // We begin by creating abbreviations for formatting modes and by declaring // objects of a number of types: //.. // int main() { // // static const int DEFAULT = bdlat_FormattingMode::DEFAULT; // static const int DEC = bdlat_FormattingMode::DEC; // static const int HEX = bdlat_FormattingMode::HEX; // static const int BASE64 = bdlat_FormattingMode::BASE64; // static const int TEXT = bdlat_FormattingMode::TEXT; // // short theShort; // unsigned theUint; // float theFloat; // const char *theCharPtr; // bsl::string theString; // // bdlt::Date theDate; // bdlt::DatetimeTz theDatetime; // bsl::vector<char> theCharVector; // bsl::vector<bsl::string> theStrVector; //.. // None of these types are generated types with metadata, so 'className' will // return a null pointer for each of them: //.. // assert(0 == bdlat_TypeName::className(theShort)); // assert(0 == bdlat_TypeName::className(theUint)); // assert(0 == bdlat_TypeName::className(theFloat)); // assert(0 == bdlat_TypeName::className(theCharPtr)); // assert(0 == bdlat_TypeName::className(theString)); // // assert(0 == bdlat_TypeName::className(theDate)); // assert(0 == bdlat_TypeName::className(theDatetime)); // assert(0 == bdlat_TypeName::className(theCharVector)); // assert(0 == bdlat_TypeName::className(theStrVector)); //.. // The 'name' function will never return a null pointer. For each of the // fundamental and vocabulary types, it returns the known type name. For // vector types, it returns the appropriate "vector<X>" string: //.. // assert(0 == bsl::strcmp("short", bdlat_TypeName::name(theShort))); // assert(0 == bsl::strcmp("unsigned int", // bdlat_TypeName::name(theUint))); // assert(0 == bsl::strcmp("float", bdlat_TypeName::name(theFloat))); // assert(0 == bsl::strcmp("const char*", // bdlat_TypeName::name(theCharPtr))); // // assert(0 == bsl::strcmp("string", bdlat_TypeName::name(theString))); // assert(0 == bsl::strcmp("bdlt::Date", bdlat_TypeName::name(theDate))); // assert(0 == bsl::strcmp("bdlt::DatetimeTz", // bdlat_TypeName::name(theDatetime))); // assert(0 == bsl::strcmp("vector<char>", // bdlat_TypeName::name(theCharVector))); // assert(0 == bsl::strcmp("vector<string>", // bdlat_TypeName::name(theStrVector))); //.. // Each of the above types except 'vector<string>' has one or more // corresponding XSD types. The XSD type is affected by a formatting mode so // that, for example, a 'vector<char>' can be represented as a text string // (formatting mode 'TEXT') or as a sequence of binary bytes (formatting mode // 'HEX' or 'BASE64'). //.. // assert(0 == bsl::strcmp("short", // bdlat_TypeName::xsdName(theShort, DEFAULT))); // assert(0 == bsl::strcmp("unsignedInt", // bdlat_TypeName::xsdName(theUint, DEFAULT))); // assert(0 == bsl::strcmp("float", // bdlat_TypeName::xsdName(theFloat, DEFAULT))); // assert(0 == bsl::strcmp("decimal", // bdlat_TypeName::xsdName(theFloat, DEC))); // assert(0 == bsl::strcmp("base64Binary", // bdlat_TypeName::xsdName(theCharVector, DEFAULT))); // assert(0 == bsl::strcmp("string", // bdlat_TypeName::xsdName(theCharVector, TEXT))); //.. // For types that have not corresponding XSD type, 'xsdName' returns // "anyType", regardless of formatting mode: //.. // assert(0 == bsl::strcmp("anyType", // bdlat_TypeName::xsdName(theStrVector, DEFAULT))); // // return 0; // } //.. // If we create our own class: //.. // namespace MyNamespace { // // class MyClass { // //... // }; //.. // Then we can assign it a printable name by overloading the // 'bdlat_TypeName_className' function in the class's namespace: //.. // const char *bdlat_TypeName_className(const MyClass&) { // return "MyClass"; // } // // } // Close MyNamespace //.. // Note that 'bdlat_TypeName_className' must return a string that is // valid and does not change for remaining duration the program. The // overloaded 'bdlat_TypeName_className' function is automatically used for // 'name' and 'xsdName', as well as for 'className': //.. // int main() // { // static const int DEFAULT = bdlat_FormattingMode::DEFAULT; // // MyNamespace::MyClass myClassObj; // // assert(0 == bsl::strcmp("MyClass", // bdlat_TypeName::className(myClassObj))); // assert(0 == bsl::strcmp("MyClass", bdlat_TypeName::name(myClassObj))); // assert(0 == bsl::strcmp("MyClass", // bdlat_TypeName::xsdName(myClassObj, DEFAULT))); // // return 0; // } //.. #include <bdlscm_version.h> #include <bdlat_bdeatoverrides.h> #include <bdlat_formattingmode.h> #include <bdlat_typetraits.h> #include <bdldfp_decimal.h> #include <bdlt_date.h> #include <bdlt_datetime.h> #include <bdlt_datetimetz.h> #include <bdlt_datetz.h> #include <bdlt_time.h> #include <bdlt_timetz.h> #include <bslalg_hastrait.h> #include <bslmf_switch.h> #include <bsls_assert.h> #include <bsls_review.h> #include <bsls_types.h> #include <bsl_string.h> #include <bsl_vector.h> #include <bsl_typeinfo.h> #include <bsl_cstring.h> namespace BloombergLP { // ===================== // struct bdlat_TypeName // ===================== struct bdlat_TypeName { // Static template functions for returning a string representation for the // name of a type. template <class TYPE> static const char *className(const TYPE& object); // Return a null-terminated string containing the exported name for // the specified 'TYPE', or a 0 pointer if 'TYPE' does not export a // name. A type exports a name by overloading the function // 'bdlat_TypeName_className(const TYPE&)' in TYPE's namespace. The // default implementation of 'bdlat_TypeName_className' will // automatically return the 'CLASS_NAME' value for types that have the // 'bdlat_TypeTraitBasicChoice', 'bdlat_TypeTraitBasicSequence', // 'bdlat_TypeTraitBasicCustomizedType', or // 'bdlat_TypeTraitBasicEnumeration' trait (i.e., types generated // using 'bas_codegen.pl'). template <class TYPE> static const char *name(const TYPE& object); // Return a null-terminated string containing the name of the specified // 'TYPE'. If 'TYPE' is a fundamental type, string, date, time, or // datetime, then return a canonical representation of the type's name. // Otherwise, if 'className' applied to the specified 'object' returns // a non-null value, then return that value. Otherwise, return // 'typeid(TYPE).name()'. Note that the returned name refers to the // *static* 'TYPE', not to the dynamic type of 'object'. template <class TYPE> static const char *xsdName(const TYPE& object, int format); // Return a null-terminated text string containing the name of the // specified 'TYPE' with the specified 'format' as it would appear in // an XML Schema (XSD) element declaration. The 'format' is // interpreted as the bit-wise OR of one or more of the values defined // in the 'bdlat_formattingmode' component. Formatting mode bits // outside of 'bdlat_FormattingMode::TYPE_MASK' are ignored. If the // specified 'object' corresponds to one of the XSD built-in types, // then return the XSD type's name. Otherwise, if 'className(object)' // returns a non-null value, then return that value. Otherwise, return // "anyType". The behavior is undefined unless the 'format' is valid // for the specified 'TYPE'. }; namespace bdlat_TypeName_Overloadable { // Namespace that provides default implementations. template <class TYPE> const char *bdlat_TypeName_className(const TYPE& object); // Default implementation of 'className' for the specified 'object'. template <class TYPE> const char *bdlat_TypeName_name(const TYPE& object); // Default implementation of 'name' for the specified 'object'. template <class TYPE> const char *bdlat_TypeName_xsdName(const TYPE& object, int format); // Default implementation of 'xsdName' for the specified 'object' and // 'format'. } // close namespace bdlat_TypeName_Overloadable // --- Anything below this line is implementation specific. Do not use. ---- // ========================= // struct bdlat_TypeName_Imp // ========================= struct bdlat_TypeName_Imp { // Private class providing implementation of 'bdlat_TypeName'. private: // PRIVATE TYPES typedef bdlat_FormattingMode FMode; struct HasClassName { }; struct IsBasicEnumeration { }; struct Other { }; // PRIVATE CLASS METHODS template <class TYPE> static const char *classNameImp(const TYPE *object, HasClassName); template <class TYPE> static const char *classNameImp(const TYPE *object, IsBasicEnumeration); template <class TYPE> static const char *classNameImp(const TYPE *object, Other); // PRIVATE CLASS DATA static const char BDLAT_NAME_BOOL[]; static const char BDLAT_NAME_CHAR[]; static const char BDLAT_NAME_SIGNED_CHAR[]; static const char BDLAT_NAME_UNSIGNED_CHAR[]; static const char BDLAT_NAME_SHORT[]; static const char BDLAT_NAME_UNSIGNED_SHORT[]; static const char BDLAT_NAME_INT[]; static const char BDLAT_NAME_UNSIGNED_INT[]; static const char BDLAT_NAME_LONG[]; static const char BDLAT_NAME_UNSIGNED_LONG[]; static const char BDLAT_NAME_INT64[]; static const char BDLAT_NAME_UINT64[]; static const char BDLAT_NAME_FLOAT[]; static const char BDLAT_NAME_DOUBLE[]; static const char BDLAT_NAME_DECIMAL64[]; static const char BDLAT_NAME_CONST_CHAR_PTR[]; static const char BDLAT_NAME_CONST_SIGNED_CHAR_PTR[]; static const char BDLAT_NAME_CONST_UNSIGNED_CHAR_PTR[]; static const char BDLAT_NAME_STRING[]; static const char BDLAT_NAME_DATE[]; static const char BDLAT_NAME_DATE_TZ[]; static const char BDLAT_NAME_DATETIME[]; static const char BDLAT_NAME_DATETIME_TZ[]; static const char BDLAT_NAME_TIME[]; static const char BDLAT_NAME_TIME_TZ[]; static const char BDLAT_NAME_VECTOR_BEGIN[]; static const char BDLAT_NAME_VECTOR_END[]; static const char BDLAT_XSDNAME_BOOLEAN[]; static const char BDLAT_XSDNAME_BYTE[]; static const char BDLAT_XSDNAME_UNSIGNED_BYTE[]; static const char BDLAT_XSDNAME_SHORT[]; static const char BDLAT_XSDNAME_UNSIGNED_SHORT[]; static const char BDLAT_XSDNAME_INT[]; static const char BDLAT_XSDNAME_UNSIGNED_INT[]; static const char BDLAT_XSDNAME_LONG[]; static const char BDLAT_XSDNAME_UNSIGNED_LONG[]; static const char BDLAT_XSDNAME_FLOAT[]; static const char BDLAT_XSDNAME_DOUBLE[]; static const char BDLAT_XSDNAME_DECIMAL64[]; static const char BDLAT_XSDNAME_DECIMAL[]; static const char BDLAT_XSDNAME_STRING[]; static const char BDLAT_XSDNAME_BASE64_BINARY[]; static const char BDLAT_XSDNAME_HEX_BINARY[]; static const char BDLAT_XSDNAME_DATE[]; static const char BDLAT_XSDNAME_DATETIME[]; static const char BDLAT_XSDNAME_TIME[]; static const char BDLAT_XSDNAME_ANY_TYPE[]; public: // CLASS METHODS template <class TYPE> static const char *className(const TYPE *); // Overloads for basic class types. template <class TYPE> static const char *name(const TYPE *); // Generic implementation for non-fundamental types. static const char *name(const bool *); static const char *name(const char *); static const char *name(const signed char *); static const char *name(const unsigned char *); static const char *name(const short *); static const char *name(const unsigned short *); static const char *name(const int *); static const char *name(const unsigned int *); static const char *name(const long *); static const char *name(const unsigned long *); static const char *name(const bsls::Types::Int64 *); static const char *name(const bsls::Types::Uint64 *); static const char *name(const float *); static const char *name(const double *); static const char *name(const bdldfp::Decimal64 *); static const char *name(const char *const *); static const char *name(const signed char *const *); static const char *name(const unsigned char *const *); static const char *name(const bsl::string *); static const char *name(const bdlt::Date *); static const char *name(const bdlt::DateTz *); static const char *name(const bdlt::Datetime *); static const char *name(const bdlt::DatetimeTz *); static const char *name(const bdlt::Time *); static const char *name(const bdlt::TimeTz *); // Overloads for fundamental types and char pointers. template <class TYPE> static const char *name(const bsl::vector<TYPE> *); // Specialization for vectors. Return the null-terminated string // constructed by replacing the "X" in the string "vector<X>" with the // result of calling 'name' on an object of the specified 'TYPE'. If // the constructed string exceeds 100 characters, then truncate to 100 // characters. Note that 'TYPE' may itself be a vector, leading to a // recursive call to this function. template <class TYPE> static const char *xsdName(const TYPE *object, int format); // Generic implementation for non-fundamental and not predefined types // using the specified 'object' and 'format'. static const char *xsdName(const bool *, int format); static const char *xsdName(const char *, int format); static const char *xsdName(const signed char *, int format); static const char *xsdName(const unsigned char *, int format); static const char *xsdName(const short *, int format); static const char *xsdName(const unsigned short *, int format); static const char *xsdName(const int *, int format); static const char *xsdName(const unsigned int *, int format); static const char *xsdName(const long *, int format); static const char *xsdName(const unsigned long *, int format); static const char *xsdName(const bsls::Types::Int64 *, int format); static const char *xsdName(const bsls::Types::Uint64 *, int format); static const char *xsdName(const float *, int format); static const char *xsdName(const double *, int format); static const char *xsdName(const bdldfp::Decimal64 *, int format); static const char *xsdName(const bsl::string *, int format); static const char *xsdName(const char *const *, int format); static const char *xsdName(const signed char *const *, int format); static const char *xsdName(const unsigned char *const *, int format); static const char *xsdName(const bdlt::Date *, int format); static const char *xsdName(const bdlt::DateTz *, int format); static const char *xsdName(const bdlt::Datetime *, int format); static const char *xsdName(const bdlt::DatetimeTz *, int format); static const char *xsdName(const bdlt::Time *, int format); static const char *xsdName(const bdlt::TimeTz *, int format); static const char *xsdName(const bsl::vector<char> *, int format); static const char *xsdName(const bsl::vector<short> *, int format); // Overloads for fundamental types and some predefined types using the // specified 'format'. static bool idempotentConcat(char *dest, int destSize, const char *segments[], int numSegments); // Concatenate the specified 'numSegments' zero-terminated strings // specified by 'segments' array and load the result into the specified // 'dest' buffer with the specified size 'destSize'. Return always // true. Note that this method is idempotent and safe for // multi-threaded environment. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------------------- // struct bdlat_TypeName_Imp // ------------------------- template <class TYPE> inline const char *bdlat_TypeName_Imp::classNameImp(const TYPE *, HasClassName) { return TYPE::CLASS_NAME; } template <class TYPE> inline const char *bdlat_TypeName_Imp::classNameImp(const TYPE *, IsBasicEnumeration) { typedef typename bdlat_BasicEnumerationWrapper<TYPE>::Wrapper Wrapper; return Wrapper::CLASS_NAME; } template <class TYPE> inline const char *bdlat_TypeName_Imp::classNameImp(const TYPE *, Other) { return 0; } template <class TYPE> inline const char *bdlat_TypeName_Imp::className(const TYPE *object) { const int k_HAS_BASIC_CHOICE_TRAIT = bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicChoice>::VALUE; const int k_HAS_BASIC_SEQUENCE_TRAIT = bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicSequence>::VALUE; const int k_HAS_BASIC_CUSTOMIZED_TYPE_TRAIT = bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicCustomizedType>::VALUE; enum { HAS_CLASS_NAME = k_HAS_BASIC_CHOICE_TRAIT | k_HAS_BASIC_SEQUENCE_TRAIT | k_HAS_BASIC_CUSTOMIZED_TYPE_TRAIT, IS_BASIC_ENUMERATION = bslalg::HasTrait<TYPE, bdlat_TypeTraitBasicEnumeration>::VALUE, SELECTOR = (HAS_CLASS_NAME ? 0 : (IS_BASIC_ENUMERATION ? 1 : 2)) }; typedef typename bslmf::Switch<SELECTOR, HasClassName, IsBasicEnumeration, Other>::Type Switch; return classNameImp(object, Switch()); } template <class TYPE> inline const char *bdlat_TypeName_Imp::name(const TYPE *object) { const char *cname = bdlat_TypeName::className(*object); return cname ? cname : typeid(TYPE).name(); } inline const char *bdlat_TypeName_Imp::name(const bool *) { return BDLAT_NAME_BOOL; } inline const char *bdlat_TypeName_Imp::name(const char *) { return BDLAT_NAME_CHAR; } inline const char *bdlat_TypeName_Imp::name(const unsigned char *) { return BDLAT_NAME_UNSIGNED_CHAR; } inline const char *bdlat_TypeName_Imp::name(const signed char *) { return BDLAT_NAME_SIGNED_CHAR; } inline const char *bdlat_TypeName_Imp::name(const short *) { return BDLAT_NAME_SHORT; } inline const char *bdlat_TypeName_Imp::name(const unsigned short *) { return BDLAT_NAME_UNSIGNED_SHORT; } inline const char *bdlat_TypeName_Imp::name(const int *) { return BDLAT_NAME_INT; } inline const char *bdlat_TypeName_Imp::name(const unsigned int *) { return BDLAT_NAME_UNSIGNED_INT; } inline const char *bdlat_TypeName_Imp::name(const long *) { return BDLAT_NAME_LONG; } inline const char *bdlat_TypeName_Imp::name(const unsigned long *) { return BDLAT_NAME_UNSIGNED_LONG; } inline const char *bdlat_TypeName_Imp::name(const bsls::Types::Int64 *) { return BDLAT_NAME_INT64; } inline const char *bdlat_TypeName_Imp::name(const bsls::Types::Uint64 *) { return BDLAT_NAME_UINT64; } inline const char *bdlat_TypeName_Imp::name(const float *) { return BDLAT_NAME_FLOAT; } inline const char *bdlat_TypeName_Imp::name(const double *) { return BDLAT_NAME_DOUBLE; } inline const char *bdlat_TypeName_Imp::name(const bdldfp::Decimal64 *) { return BDLAT_NAME_DECIMAL64; } inline const char *bdlat_TypeName_Imp::name(const char *const *) { return BDLAT_NAME_CONST_CHAR_PTR; } inline const char *bdlat_TypeName_Imp::name(const signed char *const *) { return BDLAT_NAME_CONST_SIGNED_CHAR_PTR; } inline const char *bdlat_TypeName_Imp::name(const unsigned char *const *) { return BDLAT_NAME_CONST_UNSIGNED_CHAR_PTR; } inline const char *bdlat_TypeName_Imp::name(const bsl::string *) { return BDLAT_NAME_STRING; } inline const char *bdlat_TypeName_Imp::name(const bdlt::Date *) { return BDLAT_NAME_DATE; } inline const char *bdlat_TypeName_Imp::name(const bdlt::DateTz *) { return BDLAT_NAME_DATE_TZ; } inline const char *bdlat_TypeName_Imp::name(const bdlt::Datetime *) { return BDLAT_NAME_DATETIME; } inline const char *bdlat_TypeName_Imp::name(const bdlt::DatetimeTz *) { return BDLAT_NAME_DATETIME_TZ; } inline const char *bdlat_TypeName_Imp::name(const bdlt::Time *) { return BDLAT_NAME_TIME; } inline const char *bdlat_TypeName_Imp::name(const bdlt::TimeTz *) { return BDLAT_NAME_TIME_TZ; } template <class TYPE> const char *bdlat_TypeName_Imp::name(const bsl::vector<TYPE> *) { static const int MAX_LEN = 100; static char name[MAX_LEN + 1]; static bool initialized = false; static TYPE * volatile pointer; if (! initialized) { // This is thread-safe because even if two threads execute this code // simultaneously, the same values will be written on top of each // other (i.e., the operations are idempotent). Note that the object // obtained by dereferencing 'pointer' does not exist, since 'pointer' // is null, but since it's just used for static type dispatching, it's // harmless. This code used to have the more straightforward // '*(TYPE*)0' until compilers started noticing. const char *segments[3] = { (const char*)BDLAT_NAME_VECTOR_BEGIN, bdlat_TypeName::name(*pointer), (const char*)BDLAT_NAME_VECTOR_END, }; initialized = bdlat_TypeName_Imp::idempotentConcat(name, MAX_LEN + 1, segments, 3); } return name; } template <class TYPE> inline const char *bdlat_TypeName_Imp::xsdName(const TYPE *object, int) { const char *cname = bdlat_TypeName::className(*object); return cname ? cname : (const char *)BDLAT_XSDNAME_ANY_TYPE; } inline const char *bdlat_TypeName_Imp::xsdName(const bool *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK) || FMode::e_TEXT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_BOOLEAN; } inline const char *bdlat_TypeName_Imp::xsdName(const char *, int format) { return xsdName((const signed char*)0, format); } inline const char* bdlat_TypeName_Imp::xsdName(const unsigned short *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_UNSIGNED_SHORT; } inline const char *bdlat_TypeName_Imp::xsdName(const int *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_INT; } inline const char *bdlat_TypeName_Imp::xsdName(const unsigned int *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_UNSIGNED_INT; } inline const char *bdlat_TypeName_Imp::xsdName(const long *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_INT; } inline const char* bdlat_TypeName_Imp::xsdName(const unsigned long *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_UNSIGNED_INT; } inline const char* bdlat_TypeName_Imp::xsdName(const bsls::Types::Int64 *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_LONG; } inline const char* bdlat_TypeName_Imp::xsdName(const bsls::Types::Uint64 *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK) || FMode::e_DEC == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_UNSIGNED_LONG; } inline const char* bdlat_TypeName_Imp::xsdName(const char *const *, int format) { return xsdName((const bsl::string*) 0, format); } inline const char* bdlat_TypeName_Imp::xsdName(const signed char *const *, int format) { return xsdName((const bsl::string*) 0, format); } inline const char* bdlat_TypeName_Imp::xsdName(const unsigned char *const *, int format) { return xsdName((const bsl::string*) 0, format); } inline const char *bdlat_TypeName_Imp::xsdName(const bdlt::Date *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_DATE; } inline const char *bdlat_TypeName_Imp::xsdName(const bdlt::DateTz *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_DATE; } inline const char* bdlat_TypeName_Imp::xsdName(const bdlt::Datetime *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_DATETIME; } inline const char* bdlat_TypeName_Imp::xsdName(const bdlt::DatetimeTz *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_DATETIME; } inline const char *bdlat_TypeName_Imp::xsdName(const bdlt::Time *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_TIME; } inline const char *bdlat_TypeName_Imp::xsdName(const bdlt::TimeTz *, int format) { BSLS_ASSERT(FMode::e_DEFAULT == (format & FMode::e_TYPE_MASK)); (void)format; // suppress warning if assert is disabled return BDLAT_XSDNAME_TIME; } // ------------------------------------- // namespace bdlat_TypeName_Overloadable // ------------------------------------- template <class TYPE> inline const char * bdlat_TypeName_Overloadable::bdlat_TypeName_className(const TYPE& object) { // Indirection prevents conversion to 'TYPE': return bdlat_TypeName_Imp::className(&object); } template <class TYPE> inline const char * bdlat_TypeName_Overloadable::bdlat_TypeName_name(const TYPE& object) { // Indirection prevents conversion to 'TYPE': return bdlat_TypeName_Imp::name(&object); } template <class TYPE> inline const char * bdlat_TypeName_Overloadable::bdlat_TypeName_xsdName(const TYPE& object, int format) { // Indirection prevents conversion to 'TYPE': return bdlat_TypeName_Imp::xsdName(&object, format); } // -------------------- // class bdlat_TypeName // -------------------- template <class TYPE> inline const char *bdlat_TypeName::className(const TYPE& object) { using namespace bdlat_TypeName_Overloadable; // Select function using Koenig lookup: return bdlat_TypeName_className(object); } template <class TYPE> inline const char *bdlat_TypeName::name(const TYPE& object) { using namespace bdlat_TypeName_Overloadable; // Select function using Koenig lookup: return bdlat_TypeName_name(object); } template <class TYPE> inline const char *bdlat_TypeName::xsdName(const TYPE& object, int format) { using namespace bdlat_TypeName_Overloadable; // Select function using Koenig lookup: return bdlat_TypeName_xsdName(object, format); } } // 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 ----------------------------------