Provide a namespace defining customized type functions.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide a namespace defining customized type functions.
-
- Classes:
-
- See also:
-
- Description:
- The
bdlat_CustomizedTypeFunctions
namespace
provided in this component defines parameterized functions that expose "customized type" behavior for "customized type" types. See the package-level documentation for a full description of "customized type" types. The functions in this namespace allow users to: o convert from base type to customized type ('convertFromBaseType').
o convert from customized type to base type ('convertToBaseType').
Also, the meta-function IsCustomizedType
contains a compile-time constant VALUE
that is non-zero if the parameterized TYPE
exposes "customized type" behavior through the bdlat_CustomizedTypeFunctions
namespace
.
- The
BaseType
meta-function contains a typedef Type
that specifies the base type of the value for the parameterized "customized type" type.
- This component specializes all of these functions for types that have the
bdlat_TypeTraitBasicCustomizedType
trait.
- Types that do not have the
bdlat_TypeTraitBasicCustomizedType
trait can be plugged into the bdlat
framework. This is done by overloading the bdlat_choice*
functions inside the namespace of the plugged in type. For example, suppose there is a type called mine::Cusip
(defined in the example below). In order to plug this type into the bdlat
framework as a "CustomizedType", the following functions must be declared and implemented in the mine
namespace: Also, the IsCustomizedType
meta-function must be specialized for the mine::Cusip
type in the bdlat_CustomizedTypeFunctions
namespace.
-
- Usage:
- The following snippets of code illustrate the usage of this component. Suppose we have a customized type called
Cusip
, holding an object of type bsl::string
with a restriction that the length of the string cannot be longer than nine characters. We can obtain the value of the string using the following code: Attempting to assign a string longer than nine characters will not succeed: For the purpose of this example, the class definition is as follows: The class implementation is straightforward and is deferred to the end of this usage example.
- We can now make
Cusip
expose "customized type" behavior by implementing bdlat_CustomizedTypeFunctions
for Cusip
. The first method (the longer one) overloads all the bdlat_customizedType*
functions. In the second method, we show how to bypass this by simply declaring the class mine::Cusip
to have the bdlat_TypeTraitBasicCustomizedType
trait.
-
- Longer Usage:
- First, we should forward declare all the functions that we will implement inside the
mine
namespace: Next, we provide the definitions for each of these functions: Finally, we need to specialize the IsCustomizedType
meta-function in the bdlat_CustomizedTypeFunctions
namespace for the mine::Cusip
type. This makes the bdlat
infrastructure recognize mine::Cusip
as a customized type abstraction: namespace bdlat_CustomizedTypeFunctions {
template <>
struct IsCustomizedType<mine::Cusip> {
enum { VALUE = 1 };
};
}
}
The bdlat
infrastructure (and any component that uses this infrastructure) will now recognize mine::Cusip
as a "customized" type.
-
- Shorter Usage:
- We can bypass all the code from the longer usage example by simply declaring
mine::Cusip
to have the bdlat_TypeTraitBasicCustomizedType
trait as follows: Again, the bdlat
infrastructure (and any component that uses this infrastructure) will now recognize mine::Cusip
as a "customized" type.
- For example, suppose we have the following XML data:
<?xml version='1.0' encoding='UTF-8' ?>
<Cusip>
<value>"281C82UE"</value>
</Cusip>
Using the balxml_decoder
component, we can load this XML data into a mine::Cusip
object: Note that the bdlat
framework can be used for functionality other than encoding/decoding into XML. When mine::Cusip
is plugged into the framework, then it will be automatically usable within the framework. For example, the following snippets of code will convert a string from a stream and load it into a Cusip
object: Now we have a generic function that takes an input stream and a Cusip
object, and inputs its value. We can use this generic function as follows: void usageExample()
{
using namespace BloombergLP;
bsl::stringstream ss;
mine::Cusip object;
ss << "281C82UE\n1234567890\n";
assert(0 == readCusip(ss, &object));
assert("281C82UE" == object.toString());
assert(0 != readCusip(ss, &object));
}
This concludes the usage example.
- For completeness, we finish by providing the straightforward details of the implementation of the class
Cusip
:
inline
Cusip::Cusip(bslma::Allocator *basicAllocator)
: d_value(basicAllocator)
{
}
inline
Cusip::Cusip(const Cusip& original, bslma::Allocator *basicAllocator)
: d_value(original.d_value, basicAllocator)
{
}
inline
Cusip::Cusip(const bsl::string& value, bslma::Allocator *basicAllocator)
: d_value(value, basicAllocator)
{
}
inline
Cusip::~Cusip()
{
}
inline
Cusip& Cusip::operator=(const Cusip& rhs)
{
d_value = rhs.d_value;
return *this;
}
inline
void Cusip::reset()
{
d_value.erase();
}
inline
int Cusip::fromString(const bsl::string& value)
{
enum { SUCCESS = 0, FAILURE = -1 };
globalFlag = 1;
if (9 < value.size()) {
return FAILURE;
}
d_value = value;
return SUCCESS;
}
inline
bsl::ostream& Cusip::print(bsl::ostream& stream,
int level,
int spacesPerLevel) const
{
return bdlb::PrintMethods::print(stream,
d_value,
level,
spacesPerLevel);
}
inline
const bsl::string& Cusip::toString() const
{
globalFlag = 2;
return d_value;
}
inline
bool geom::operator==(const geom::Cusip& lhs,
const geom::Cusip& rhs)
{
return lhs.d_value == rhs.d_value;
}
inline
bool geom::operator!=(const geom::Cusip& lhs,
const geom::Cusip& rhs)
{
return lhs.d_value != rhs.d_value;
}
inline
bsl::ostream& geom::operator<<(bsl::ostream& stream,
const geom::Cusip& rhs)
{
return rhs.print(stream, 0, -1);
}