Quick Links: |
Provide a NameOf
type for displaying template type at run-time.
More...
Namespaces | |
namespace | bsls |
NameOf
type for displaying template type at run-time. bsls::NameOf | template class to return name of template parameter |
bsls::nameOfType(const TYPE&): template function to return name of TYPE
bsls::NameOf<TYPE>
, which can implicitly cast to a const char *
which will point to a description of TYPE
. using
statements so that the template class NameOf
and the template function nameOfType
can be referred to concisely, without having to qualify them with namespaces on each call. Note that if you've already said using namespace BloombergLP
you don't have to give the BloombergLP::
qualifiers here: using BloombergLP::bsls::NameOf; using BloombergLP::bsls::nameOfType;
namespace { struct MyType { int d_i; char d_c; }; union MyUnion { int d_i; char d_buffer[100]; }; } // close unnamed namespace
NameOf
template class, when created with a type, can be implicitly cast to a const char *
which points to a description of the type. assert(!std::strcmp("double", NameOf<double>())); assert(!std::strcmp("int", NameOf<int>()));
NameOf
is passed a typedef
or template parameter, it resolves it to the original type: typedef int Woof; assert(!std::strcmp("int", NameOf<Woof>()));
nameOfType
template function, which takes as any variable as an argument, and returns a const char *
pointing to a description of the type of the variable. int ii = 2; assert(!std::strcmp("int", nameOfType(ii)));
NameOf
and nameOfType
will strip BloombergLP::
namespace qualifiers, as well as anonymous namespace qualifiers. typedef BloombergLP::bsls::Stopwatch SW; const SW sw; const MyType mt = { 2, 'a' }; MyUnion mu; mu.d_i = 7; assert(!std::strcmp("bsls::Stopwatch", NameOf<SW>())); assert(!std::strcmp("bsls::Stopwatch", NameOf<BloombergLP::bsls::Stopwatch>())); assert(!std::strcmp("bsls::Stopwatch", nameOfType(sw))); assert(!std::strcmp("MyType", NameOf<MyType>())); assert(!std::strcmp("MyType", nameOfType(mt))); assert(!std::strcmp("MyUnion", NameOf<MyUnion>())); assert(!std::strcmp("MyUnion", nameOfType(mu)));
NameOf
type to const char *
for initializing or comparing with std::string
s. To facilitate, NameOf
provides a const char *
name
accessor, to avoid the user having to do a more verbose static cast
. const std::string swName = "bsls::Stopwatch"; assert(swName == static_cast<const char *>(NameOf<SW>())); assert(swName == NameOf<SW>().name()); const std::string swNameB = NameOf<SW>().name(); assert(swNameB == swName); printf("NameOf<SW>() = \"%s\"\n", NameOf<SW>().name()); printf("NameOfType(4 + 3) = \"%s\"\n", nameOfType(4 + 3));
nameOfType
naturally returns a const char *
and needs no help casting. Note also that bsls::debugprint
is able to figure out how to cast NameOf
directly to const char *
with no problems, as can iostreams, so there is no problem with putting a NameOf
in a LOOP_ASSERT
or ASSERTV
. It is anticipated that displaying by the BDE ASSERTV
, LOOP_ASSERT, and 'P
macros will be the primary use of this component. printf("NameOf<double>() = "); BloombergLP::bsls::debugprint(NameOf<double>()); printf("\n"); typedef double DTYPE; DTYPE x = 7.3; LOOP_ASSERT(NameOf<DTYPE>(), x > 7); std::string myStr; // Assign, not init, of string doesn't need myStr = NameOf<DTYPE>(); // '.name()'. assert("double" == myStr);
NameOf<SW>() = "bsls::Stopwatch"
NameOf
and nameOfType
will simplify std::basic_string<...>
declarations to std::string
. const std::string s = "std::string"; assert(s == NameOf<std::basic_string<char> >().name()); assert(s == NameOf<std::string>().name()); assert(s == nameOfType(s)); typedef NameOf<std::string> Nos; const std::string s2 = "bsls::NameOf<std::string>"; assert(s2 == NameOf<NameOf<std::basic_string<char> > >().name()); assert(s2 == NameOf<NameOf<std::string> >().name()); assert(s2 == NameOf<Nos>().name()); assert(s2 == nameOfType(Nos()));