Back to Arangodb

Serialization

3rdParty/boost/1.78.0/libs/serialization/doc/smart_cast.html

3.12.9.13.1 KB
Original Source

|

|

Serialization

smart_cast

|


Motivation

To cast from one type to another related type, C++ provides the following operators:static_cast<T *<>(U *)static_cast<T &<>(U &)

  • required if neither T nor U are polymorphic
  • permitted in other cases.
  • fails to detect erroneous casts of polymophic pointers/references at runtime.
  • does not permit "cross casting"
  • inline function calls can be optimized away during compile time.

dynamic_cast<T *<>(U *)dynamic_cast<T &<>(U &)

  • permitted if either T or U are polymorphic
  • prohibited in other cases.
  • throws exception on detecting erroneous casts of polymorphic pointers/references at runtime.
  • permits "cross casting"
  • cannot optimise inline virtual functions at compile time.

These rules can make it difficult to use casting with a function template argument. Consider the following example:

#include <boost/serialization/smart_cast.hpp>

struct top {
};

struct base1 : public top {
    bool is_storable() const {
        return true;
    }
    virtual ~base1();
};

struct base2 {
    virtual ~base2();
};

struct derived1 :
    public base1
{
    derived1();
};

struct derived2 :
    public base1, 
    public base2
{
    derived2();
};

template<class T>
bool is_storable(T &t){
    // what type of cast to use here?

    // this fails at compile time when T == base2
    // return static_cast<base1 &>(t).is_storable();

    // this fails at compile time when T == top
    // otherwise it works but cannot optimize inline function call
    // return dynamic_cast<base1 &>(t).is_storable();

    // this always works - and is guaranteed to generate the fastest code !
    return (boost::smart_cast_reference<base1 &>(t)).is_storable();
}

int main(){
    derived1 d1;
    top & t1 = d1;
    derived2 d2;
    base2 & b2 = d2;

    bool result;
    result = is_storable(d1);   
    result = is_storable(d2);   
    result = is_storable(b2);
    result = is_storable(b2);
    result = is_storable(t1);
    return 0;
}

The serialization library includes a mix of classes which use both static polymorphism ( CRTP ) and dynamic polymorphism via virtual functions. smart_cast was written to address the more problematic manifestations of the situation exemplified above.

Usage

The following syntax is supported:

smart_cast<Target *, Source *>(Source * s);
smart_cast<Target *>(Source * s);
smart_cast<Target &, Source &&gt(Source & s);

Note that the above syntax doesn't include

smart_cast<Target & &gt(Source & s)

but the same functionality is supported with the following special syntax

smart_cast_reference<Target &&gt(Source & s)

Requirements

smart_cast can be used only on compilers that support partial template specialization or on types for which the macro BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(<type>) has been applied.


© Copyright Robert Ramey 2002-2004. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE\_1\_0.txt)