Quick Links:

bal | bbl | bdl | bsl

Classes | Typedefs | Enumerations | Functions

Component bslmf_isconvertible
[Package bslmf]

Provide a compile-time check for type conversion. More...

Classes

struct  bslmf::IsConvertible_CheckComplete< t_TYPE &, false >
struct  bslmf::IsConvertible_CheckComplete< t_TYPE, true >
struct  bslmf::IsConvertible_CheckComplete< t_TYPE[], false >
struct  bslmf::IsConvertible_Match::no_type
struct  bslmf::IsConvertible_Imp< t_FROM_TYPE, t_TO_TYPE >
struct  bslmf::IsConvertible_LazyTrait< t_TO_TYPE >
struct  bslmf::IsConvertible_IsNeverConvertible< t_FROM_TYPE, t_TO_TYPE >
struct  bslmf::IsConvertible_FilterNeverConvertible< t_FROM_TYPE, t_TO_TYPE >
struct  bslmf::IsConvertible_Conditional< t_FROM_TYPE, t_TO_TYPE >
struct  bsl::is_convertible_dispatch< t_TYPE, t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE, const t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE, t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE, const t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE, t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE, const t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE, t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE, const t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE &, t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE &, const t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE &, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< t_TYPE &, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE &, t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE &, const t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE &, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const t_TYPE &, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE &, t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE &, const t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE &, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE &, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE &, t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE &, const t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE &, volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< const volatile t_TYPE &, const volatile t_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_TYPE, t_TYPE >
struct  bsl::is_convertible_dispatch< t_FROM_TYPE, volatile t_TO_TYPE & >
struct  bsl::is_convertible_dispatch< t_FROM_TYPE, const volatile t_TO_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, volatile t_TO_TYPE & >
struct  bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, const volatile t_TO_TYPE & >
struct  bsl::EffectiveFromType< t_FROM_TYPE >
struct  bsl::is_convertible_dispatch< volatile t_FROM_TYPE &, t_TO_TYPE >
struct  bsl::is_convertible< t_FROM_TYPE, t_TO_TYPE >

Typedefs

typedef bsl::integral_constant
< bool, value > 
bslmf::IsConvertible_Imp::type

Enumerations

enum  { bslmf::IsConvertible_CheckComplete::k_CHECK_COMPLETE = sizeof(t_TYPE) }
enum  { bslmf::IsConvertible_Imp::value }

Functions

static yes_type bslmf::IsConvertible_Match::match (IsConvertible_Match &)
template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match (const t_TYPE &)
template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match (const volatile t_TYPE &)
template<class t_TYPE >
static bsl::enable_if
< bsl::is_function< t_TYPE >
::value, no_type >::type 
bslmf::IsConvertible_Match::match (t_TYPE &)

Detailed Description

Outline
Purpose:
Provide a compile-time check for type conversion.
Classes:
bsl::is_convertible standard meta-function for type conversion checking
bsl::is_convertible_v the result value of bsl::is_convertible
bslmf::IsConvertible meta-function for type conversion checking
See also:
Component bslmf_integralconstant
Description:
This component defines two meta-functions, bsl::is_convertible and BloombergLP::bslmf::IsConvertible and a template variable bsl::is_convertible_v, that represents the result value of the bsl::is_convertible meta-function. All these meta-functions may be used to check whether an implicit conversion exists from one type to another.
bsl::is_convertible meets the requirements of the is_convertible template defined in the C++11 standard [meta.rel], while bslmf::IsConvertible was devised before is_convertible was standardized.
The two meta-functions are functionally equivalent except that bsl::is_convertible does not allow its template parameter types to be incomplete types according to the C++11 standard while bslmf::IsConvertible tests conversions involving incomplete types. The other major difference between them is that the result for bsl::is_convertible is indicated by the class members value and type, whereas the result for bslmf::IsConvertible is indicated by the class members VALUE and Type.
Note that bsl::is_convertible should be preferred over bslmf::IsConvertible, and in general, should be used by new components. Also note that bsl::is_convertible and bslmf::IsConvertible can produce compiler errors if the conversion is ambiguous. For example:
  struct A {};
  struct B : public A {};
  struct C : public A {};
  struct D : public B, public C {};

  static int const C = bsl::is_convertible<D*, A*>::value;  // ERROR!
Also note that the template variable is_convertible_v is defined in the C++17 standard as an inline variable. If the current compiler supports the inline variable C++17 compiler feature, bsl::is_convertible_v is defined as an inline constexpr bool variable. Otherwise, if the compiler supports the variable templates C++14 compiler feature, bsl::is_convertible_v is defined as a non-inline constexpr bool variable. See BSLS_COMPILERFEATURES_SUPPORT_INLINE_VARIABLES and BSLS_COMPILERFEATURES_SUPPORT_VARIABLE_TEMPLATES macros in bsls_compilerfeatures component for details.
Usage:
In this section we show intended use of this component.
Example 1: Select Function Based on Type Convertibility:
The bsl::is_convertible meta-function can be used to select an appropriate function (at compile time) based on the convertibility of one type to another without causing a compiler error by actually trying the conversion.
First, we define two classes, Foo and Bar. The Foo class has an explict constructor from int, an implicit conversion operator that returns an integer value while the Bar class does neither:
  class Foo {
      // DATA
      int d_value;

    public:
      // CREATORS
      explicit Foo(int value) : d_value(value) {}

      // ACCESSORS
      operator int() const { return d_value; }
  };

  class Bar {};
Then, we run: Note that int to Foo is false, even though Foo has a constructor that takes an int. This is because that constructor is explicit, and is_converitble ignores explicit constructors.
Next, we go on to demonstrate how this could be used. Suppose we are implementing a convertToInt template method that converts a given object of the (template parameter) t_TYPE to int type, and returns the integer value. If the given object can not convert to int, return 0. The method calls an overloaded function, getIntValue, to get the converted integer value. The idea is to invoke one version of getIntValue if the type provides a conversion operator that returns an integer value, and another version if the type does not provide such an operator.
We define the first getIntValue function that takes a bsl::false_type as its last argument, whereas the second getIntValue function takes a bsl::true_type object. The result of the bsl::is_convertible meta-function (i.e., its type member) is used to create the last argument passed to getIntValue. Neither version of getIntValue makes use of this argument -- it is used only to differentiate the argument list so we can overload the function.
  template <class t_TYPE>
  inline
  int getIntValue(t_TYPE *, bsl::false_type)
  {
      // Return 0 because the specified 't_TYPE' is not convertible to the
      // 'int' type.

      return 0;
  }

  template <class t_TYPE>
  inline
  int getIntValue(t_TYPE *object, bsl::true_type)
  {
      // Return the integer value converted from the specified 'object' of
      // the (template parameter) 't_TYPE'.

      return int(*object);
  }
Now, we define our convertToInt method:
  template <class t_TYPE>
  inline
  int convertToInt(t_TYPE *object)
  {
      typedef typename bsl::is_convertible<t_TYPE,
                                           int>::type CanConvertToInt;
      return getIntValue(object, CanConvertToInt());
  }
Notice that we use bsl::is_convertible to get a bsl::false_type or bsl::true_type, and then call the corresponding overloaded getIntValue method.
Finally, we call our finished product and observe the return values:
  Foo foo(99);
  Bar bar;

  assert(99 == convertToInt(&foo));
  assert(0  == convertToInt(&bar));

Typedef Documentation

template<class t_FROM_TYPE , class t_TO_TYPE >
typedef bsl::integral_constant<bool, value> bslmf::IsConvertible_Imp< t_FROM_TYPE, t_TO_TYPE >::type [inherited]

Enumeration Type Documentation

template<class t_TYPE, bool = bsl::is_function<t_TYPE>::value || bsl::is_void<t_TYPE>::value>
anonymous enum [inherited]
Enumerator:
k_CHECK_COMPLETE 
template<class t_FROM_TYPE , class t_TO_TYPE >
anonymous enum [inherited]
Enumerator:
value 

Function Documentation

static yes_type bslmf::IsConvertible_Match::match ( IsConvertible_Match  )  [static, inherited]

Return yes_type if called on IsConvertible_Match type.

template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match ( const t_TYPE &   )  [static, inherited]

Return yes_type if the (template parameter) t_TYPE is IsConvertible_Match, and no_type otherwise.

template<class t_TYPE >
static no_type bslmf::IsConvertible_Match::match ( const volatile t_TYPE &   )  [static, inherited]

Return yes_type if the (template parameter) t_TYPE is IsConvertible_Match and no_type otherwise.

template<class t_TYPE >
static bsl::enable_if<bsl::is_function<t_TYPE>::value, no_type>::type bslmf::IsConvertible_Match::match ( t_TYPE &   )  [static, inherited]

Return yes_type if the (template parameter) t_TYPE is IsConvertible_Match and no_type otherwise.