So you've decided that you want to convert some of your dynamically
polymorphic classes into statically polymorphic classes. Now what?

In chapter ref(POLYMORPHISM) the base class tt(Vehicle) and some derived
classes were introduced. tt(Vehicle, Car) and tt(Truck)'s interfaces look like
this (regarding the members that are involved in their polymorphic behaviors):
        verb(
    class Vehicle
    {
        public:
            int mass() const;

        private:
            virtual int vmass() const;
    };

    class Car: public Vehicle
    {
        private:
            int vmass() const override;
    };
        
    class Truck: public Car
    {
        private:
            int vmass() const override;
    };
        )

    When converting dynamically polymorphic classes to statically polymorphic
classes we must realize that polymorphic classes show two important
characteristics:
    itemization(
    it() they define facilities (data members, member functions) that are
inherited by derived classes (e.g., tt(Vecicle::mass)) (i.e., the inheritable
interface), and
    it() derived classes implement the redefinable interface in a way that
suits their purpose (e.g., tt(Truck::vmass)).
    )

With statically polymorphic classes these two characteristics should
completely be separated.  As we've seen in the previous section, a
statically polymorphic derived class derives from its base class by using its
own class type as argument to the base class's type parameter. This works fine
if there's only one level of inheritance (i.e., one base class, and one or
more classes that are directly derived from that base class).

With multiple levels of inheritance (e.g., tt(Truck -> Car -> Vehicle))
tt(Truck)'s inheritance specification becomes a problem. Here's an intial
attempt to use atatic polymorphism and multiple levels of inheritance:
        verb(
    template <class Derived>
    class Vehicle
    {
        public:
            void mass() 
            {
                static_cast<Derived *>(this)->vmass();
            }
    };
    
    class Car: public Vehicle<Car>
    {
        friend void Vehicle<Car>::mass();
        void vmass();
    };

    class Truck: public Car
    {
        void vmass();
    };
        )
        itemization(
        it() If tt(Truck) inherits from tt(Car), then tt(Truck) implicitly
derives from tt(Vehicle<Car>), as tt(Car) derives from
tt(Vehicle<Car>). Consequently, when tt(Truck{}.mass()) is called it is not
tt(Truck::vmass) that's activated, but em(Car's) tt(vmass) function. But
tt(Truck) em(must) derive from tt(Car) in order to use tt(Car's) protected
features and to add tt(Car's) public features to its own public
interface. COMMENT(see examples/staticpolymorphism/double.cc)
        it() Multiple inheritance also doesn't solve the issue: when
inheriting tt(Truck) from tt(Vehicle<Truck>) em(and) from tt(Car) 
results in a class tt(Truck) that em(also) inherits from
tt(Vehicle<Car>) (through tt(Truck's Car) base class), and compilation fails
as the compiler encounters an ambiguity when instantiating tt(Vehicle::mass):
should it call tt(Class::vmass) or should it call tt(Truck::vmass)?
    COMMENT(see examples/staticpolymorphism/multiple.cc)
    )
    To solve this problem (i.e., to ensure that tt(Truck{}.mass()) calls
tt(Truck::vmass)) the redefinable interface must be separated 
from the inheritable interface.

In derived classes the protected and public interfaces of (direct or indirect)
base classes are made available using standard inheritance. This is shown in
the left-hand side of figure ref(STATPOLY).  

    figure(classtemplates/converting)
        (Vehicle Static Polymorphic Class Design)(STATPOLY)

The left-hand side classes are used as base classes for the next level of
inheritance (except for tt(TruckBase), but tt(TruckBase) could be used as base
class for yet another level of class inheritance). This line of inheritance
declares the inheritable interface of the classes.

Each of the classes to the left is a base class of a single class to the
right: tt(VehicleBase) is a base class for tt(Vehicle), tt(TruckBase) for
tt(Truck). The classes to the left contain all members that are completely
independent of the elements that are involved in realizing the static
polymorphism. As that's a mere design principle to realize multiple levels of
static polymorphism the common data hiding principles are relaxed, and the
left-hand side classes declare their matching right-hand side derived class
templates as friend, to allow full access to all members of a left-hand side
class, including the private members, from the matching derived class template
to the right. E.g., tt(VehicleBase) declares tt(Vechicle) as its friend:
        verb(
    class VehicleBase
    {
        template <class Derived>
        friend class Vehicle;

        // all members originally in Vehicle, but not involved 
        // in realizing static polymorphism are declared here. E.g.,
        size_t d_massFactor = 1;
    };
        )    

The top level class to the left (tt(VehicleBase)) lays the foundation of
static polymorphism, by defining that part of the interface that uses the
statically redefinable functions. E.g, using the curiously recurring template
pattern it defines a class member tt(mass) that calls the function tt(vmass)
of its derived class (in addition it can use all members of its non-class
template base class). E.g,:
        verb(
    template <class Derived>
    class Vehicle: public VehicleBase
    {
        public:
            int mass() const
            {
                return d_massFactor *
                        static_cast<Derived const *>(this)->vmass();
            }
    };
        )

Which function actually is called when tt(vmass) is called depends on the
implementation in the class tt(Derived), which is handled by the remaining
classes, shown below tt(Vehicle), which are all derived from tt(Vehicle) (as
well as from their own tt(...Base) class). These classes use the curiously
recurring template pattern. E.g.,
        verb(
    class Car: public CarBase, public Vehicle<Car>
        )
    So, if tt(Car) now implements its own tt(vmass) function, which can use
any of its own (i.e., tt(CarBase's) members), then em(that) function is called
when calling a tt(Vehicle's mass) function. E.g.,
        verb(
    template <class Vehicle>
    void fun(Vehicle &vehicle)
    {
        cout << vehicle.mass() << '\n';
    }
    
    int main()
    {
        Car car;
        fun(car);       // Car's vmass is called
    
        Truck truck;
        fun(truck);     // Truck's vmass is called
    }
        )

Now that we've analyzed the design of statically polymorphic classes using
multiple levels of inheritance let's summarize the steps that took to
implement static polymorphism
    itemization(
    it() First, starting at the base class,
the class tt(Vehicle). tt(Vehicle's) non-redefinable interface is moved
to a class tt(VehicleBase), and tt(Vehicle) itself is turned into a statically
polymorphic base class. In general all members of the original 
polymorphic base class that do not use or implement virtual members should be
moved to the tt(XBase) class. 

    it() tt(VehicleBase) declares tt(Vehicle) to be a tt(friend), to allow
tt(Vehicle) full access to its former members, that are now in
tt(VehicleBase).

    it() tt(Vehicle's) members refer to the redefinable interface. I.e., its
members call members of its tt(Derived) template type parameter.  In this
implementation tt(Vehicle) does not implement its own tt(vmass) member. We
cannot define tt(Vehicle<Vehicle>), and with static polymorphism the base
class is essentially comparable to an abstract base class. If this is
inconvenient then a default class can be specified for tt(Vehicle's Derived)
class, implementing the redefinable interface of the original 
polymorphic base class (allowing for definitions like tt(Vehicle<> vehicle)).

    it() Likewise the remaining classes have their members not involved in
static polymorphism moved to a base class. E.g., 
class tt(Car) moves these members to  tt(CarBase) and
tt(Truck) moves those members to  tt(TruckBase).  

    it() A standard linear line of inheritance is used from tt(VehicleBase) to
tt(CarBase) and from there to tt(TruckBase).

    it() Each of the remaining classes (here: tt(Car) and tt(Truck)) is a
class template that derives from its base classes, and also, using the
curiously recurrent template pattern, from tt(Vehicle).

    it() Each of these remaining classes can now implement its own version of
the redefinable interface, as used by the members of tt(Vehicle).
    )

    This design pattern can be extended to any level of inheritance: for each
new level a base class is constructed, deriving from the most deeply nested
tt(XXXBase) class so far, and deriving from tt(Vehicle<XXX>), implementing its
own ideas about the redefinable interface.
    
    Functions that are used in combination with statically polymorphic classes
themselves must be function templates. E.g.,
        verb(
    template <class Vehicle>
    void fun(Vehicle &vehicle)
    {
        cout << vehicle.mass() << '\n';
    }
        )
    Here, tt(Vehicle) is just a formal name. When an object is passed to
tt(fun) it must offer a member tt(mass), or compilation will fail. If the
object is in fact a tt(Car) or tt(Truck), then their tt(Vehicle<Type>) static
base class member tt(mass) is called, which in turn uses static polymorphism
to call the member tt(vmass) as implemented by the actually passed class
type. The following tt(main) function displays, respectively, 1000 and 15000:
        verb(
    int main()
    {
        Car car;
        fun(car);
    
        Truck truck;
        fun(truck);
    }
        )
    Note that this program implements tt(fun) twice, rather than once in the
case of dynamic polymorphism. The same holds true for the tt(Vehicle) class
template: two implementations, one for the tt(Car) type, and one for the
tt(Truck) type. The statically polymorphic program will be slightly faster,
though.

    (A compilable example using static polymorphism is found in the
annotations()'s source distribution's file
tt(yo/classtemplates/examples/staticpolymorphism/polymorph.cc).)
