Any of union classes: type_union, iterator_union, or ContainerUnion.

### Prerequisits

    #include <ContainerUnion.h>
    using namespace polymake;

The old good union inherited from C can only swallow primitive data without constructors and destructors (so called POD types.) There is no analogous construction for arbitrary user-defined types. One attempt to remedy this has been made in the Boost library with any_type: it can hold really any data type.

Polymake offers a similar construction, which, however, come closer to the original union idea in that the set of types assignable to it is strictly defined at the compile time. In the fact, there are three unions, the first one being the base of the others:

template <typename TypeList> class type_union; template <typename TypeList> class iterator_union; template <typename TypeList> class ContainerUnion;

TypeList is a cons list of data types. Only types listed there can be stored in the union; the checking is performed at compile time.

A type in a list can be also a reference. In this case the union contains a pointer to the data, the latter is expected to be stored elsewhere. You should not specify a data type and a reference to it in the same type list, as these cases can't be distinguished during the assignment.

union();
The default constructor creates an uninitialized union object.
union (const union&);
The copy constructor of the union calls the copy constructor of the data type currently stored in the source union object. If the current contained type is a reference, only the internal pointer is being copied.
template <typename Source> union (const Source&);
Store the copy of the given data (or a pointer to it if declared as a reference in the type list). If Source does not occur in the type list, the compiler will emit an obscure error message.
template <typename Source> union& union::operator= (const Source&);
The action depends on the old contents of the union. If it already contains data of type Source, then the suitable assignment operator is called. Otherwise the old contents are destroyed and the new contents created as in the constructor described above.
bool union::valid() const;
Return true if it was filled by a constructor or assignment. Return false if it was unchanged since creation by default constructor.
Type* type_cast<Type*> (union&); const Type* type_cast<Type*> (const union&);
Compare the data type currently stored in the union with Type. If identical, return the internal address of the stored data (or the stored pointer in the reference case.) If not, or the union is uninitialized, return 0.
Type must be really identical (up to the reference attribute) to one of the allowed types from the list. Currently, this function knows nothing about derived classes, nor about built-in or user-defined type conversions. It may become more elaborated in the future, if the need arises.

iterator_union and ContainerUnion are derived from type_union. They implement the standard iterator and container interface respectively. As the name suggests, all types in an iterator_union list must be iterators, as well as all types in a ContainerUnion list must be containers. In the case the listed component classes are of different categories, the interface implemented by the union corresponds to the most common category. For example, a union of a forward and random-access iterator will offer an interface of forward iterator.

An intricate issue is the determination of a right data type pointed to by the iterator_union. The decision is made, based on the typename std::iterator_traits::reference for all component types, along the following rules:

- If all reference types are identical, the solution is trivial.
- If all reference types are really references and they point to classes related to each other by inheritance, then the reference of the union is a reference to the least-derived class.
- If all reference are containers, the resulting reference is a ContainerUnion
- Otherwise the resulting reference is a type_union. No attempt is made to find a built-in or user-defined conversion between the data types. If you prefer to have such a conversion instead of creating type_union objects, you must wrap some of the data containers participating in the union in a TransformedContainer.

ContainerUnion decides about its iterator type along similar lines:

- If the iterators of all component containers are of the same type, it is also the iterator of the union.
- If all iterators are physical pointers and they point to classes related to each other by inheritance, then the resulting iterator is a pointer to the least-derived class.
- Otherwise the iterator is a iterator_union of iterators of the component containers.