Analysis of Loki's TypeList Technology

Source: Internet
Author: User

Loki's generalized programming is amazing, and the most important technology is the type linked list. Even the tuple of boost is compiled in imitation of it, which shows how high the technology level is. Loki's TypeList design philosophy mainly includes two points:

1. the biased Technology of templates is described in the previous article.

2. template iteration.

I. the biased template technology enables it to end iteration after a certain number of iterations, so that it will not keep repeating. It ends at a certain level. Next, let's take a look at the magic of TypeList and see how Andrei makes the template so magical.

Class NullType {};


Template

Struct TypeList

{

Typedef T Head;

Typedef U Tail;

};

The definition of TypeList is very simple. The template type is Head and Tail, while Tail is similar to the Tail NULL pointer of the linked list. But here it is not a NULL pointer, but NullType. Tail is also a collection of TypeList. This step-by-step expansion is similar to a linked list, as shown in the following code:

Typedef TypeList , TypeList >>> IntDoubleCharUnIntType;

Int double char unsiged int forms a linked list and ends with NullType.

Ii. List operations

1. Calculate the length of the linked list

All those who have learned about the data structure linked list should know that the length of the linked list is calculated based on the length of the traversal chain table until NULL. The same is true here. We can also implement it in a similar way. But it is implemented in iterative form.

<1> declare the Length template class. The declaration here is for a reason. One is to declare the following two special features. The other is to ensure that the template parameter can only be NullType or TypeList type during use.

Template Struct Length;


<2> Use NullType to customize the Length template class

Template <>

Length

{

Enum {value = 0 ,}; // Length

};


<3> If TypeList is used for feature, it should be noted that I have never figured out why the Length has only one template parameter, but the template is used to define the Length. However, there are two examples. Is this not the special feature of the Length template class? It is only to show that the TypeList type is used for the special feature during the special feature, however, TypeList requires two parameters during the special process.

So here we can use recursive methods. See the following code.

Template

Length >

{

Enum {value = 1 + Length: Value ,};

}

Here, because the U type is still a type linked list TypeList after expansion, you can continue recursion until the end of NullType. In this way, the length of the linked list can be calculated. What a magic !!!

In addition, the preceding Length Declaration creates an implicit limitation for the following part, that is, when the Length template class is used, it can only be TypeList and NullType, because only these two types implement the special Length, if you input another type such as Length : Value and so on are not compiled in the past, because the Length special int version is not implemented, there is only one Length declaration. We can see that this kind of programming is clever and unique in design. It is really amazing !!!!!! Admire !!!!!!

Other operations of TypeList similar to the vector data structure, such as indexOf, Append, and Erase, are implemented through similar methods. The principle is to declare an operation function class, two special classes are used to implement one recursive operation and the other end-to-end operation. For the rest, see the following code. I will not explain it in detail here. I will share with you here. Every day, we take a small step, and a long time is a huge step.

    template 
  
       struct Typelist    {       typedef T Head;       typedef U Tail;    };// Typelist utility algorithms    namespace TL    {////////////////////////////////////////////////////////////////////////////////// class template MakeTypelist// Takes a number of arguments equal to its numeric suffix// The arguments are type names.// MakeTypelist
   
    ::Result// returns a typelist that is of T1, T2, ...////////////////////////////////////////////////////////////////////////////////        template        <            typename T1  = NullType, typename T2  = NullType, typename T3  = NullType,            typename T4  = NullType, typename T5  = NullType, typename T6  = NullType,            typename T7  = NullType, typename T8  = NullType, typename T9  = NullType,            typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,            typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,            typename T16 = NullType, typename T17 = NullType, typename T18 = NullType        >         struct MakeTypelist        {        private:            typedef typename MakeTypelist            <                T2 , T3 , T4 ,                 T5 , T6 , T7 ,                 T8 , T9 , T10,                 T11, T12, T13,                T14, T15, T16,                 T17, T18            >            ::Result TailResult;        public:            typedef Typelist
    
      Result;        };        template<>        struct MakeTypelist<>        {            typedef NullType Result;        };////////////////////////////////////////////////////////////////////////////////// class template Length// Computes the length of a typelist// Invocation (TList is a typelist):// Length
     
      ::value// returns a compile-time constant containing the length of TList, not counting//     the end terminator (which by convention is NullType)////////////////////////////////////////////////////////////////////////////////        template 
      
        struct Length; template <> struct Length
       
         { enum { value = 0 }; }; template 
        
          struct Length< Typelist
         
           > { enum { value = 1 + Length
          ::value }; };////////////////////////////////////////////////////////////////////////////////// class template TypeAt// Finds the type at a given index in a typelist// Invocation (TList is a typelist and index is a compile-time integral // constant):// TypeAt  ::Result// returns the type in position 'index' in TList// If you pass an out-of-bounds index, the result is a compile-time error//////////////////////////////////////////////////////////////////////////////// template  struct TypeAt; template  struct TypeAt  , 0> { typedef Head Result; }; template  struct TypeAt  , i> { typedef typename TypeAt  ::Result Result; };////////////////////////////////////////////////////////////////////////////////// class template TypeAtNonStrict// Finds the type at a given index in a typelist// Invocations (TList is a typelist and index is a compile-time integral // constant):// a) TypeAt  ::Result// returns the type in position 'index' in TList, or NullType if index is // out-of-bounds// b) TypeAt  ::Result// returns the type in position 'index' in TList, or D if index is out-of-bounds//////////////////////////////////////////////////////////////////////////////// template  struct TypeAtNonStrict { typedef DefaultType Result; }; template  struct TypeAtNonStrict  , 0, DefaultType> { typedef Head Result; }; template  struct TypeAtNonStrict  , i, DefaultType> { typedef typename TypeAtNonStrict  ::Result Result; };////////////////////////////////////////////////////////////////////////////////// class template IndexOf// Finds the index of a type in a typelist// Invocation (TList is a typelist and T is a type):// IndexOf  ::value// returns the position of T in TList, or NullType if T is not found in TList//////////////////////////////////////////////////////////////////////////////// template  struct IndexOf; template  struct IndexOf  { enum { value = -1 }; }; template  struct IndexOf  , T> { enum { value = 0 }; }; template  struct IndexOf  , T> { private: enum { temp = IndexOf  ::value }; public: enum { value = (temp == -1 ? -1 : 1 + temp) }; };////////////////////////////////////////////////////////////////////////////////// class template Append// Appends a type or a typelist to another// Invocation (TList is a typelist and T is either a type or a typelist):// Append  ::Result// returns a typelist that is TList followed by T and NullType-terminated//////////////////////////////////////////////////////////////////////////////// template  struct Append; template <> struct Append  { typedef NullType Result; }; template  struct Append  { typedef Typelist  Result; }; template  struct Append  > { typedef Typelist  Result; }; template  struct Append  , T> { typedef Typelist  ::Result> Result; }; ////////////////////////////////////////////////////////////////////////////////// class template Erase// Erases the first occurence, if any, of a type in a typelist// Invocation (TList is a typelist and T is a type):// Erase  ::Result// returns a typelist that is TList without the first occurence of T//////////////////////////////////////////////////////////////////////////////// template  struct Erase; template  // Specialization 1 struct Erase  { typedef NullType Result; }; template  // Specialization 2 struct Erase  , T> { typedef Tail Result; }; template  // Specialization 3 struct Erase  , T> { typedef Typelist  ::Result> Result; };////////////////////////////////////////////////////////////////////////////////// class template EraseAll// Erases all first occurences, if any, of a type in a typelist// Invocation (TList is a typelist and T is a type):// EraseAll  ::Result// returns a typelist that is TList without any occurence of T//////////////////////////////////////////////////////////////////////////////// template  struct EraseAll; template  struct EraseAll  { typedef NullType Result; }; template  struct EraseAll  , T> { // Go all the way down the list removing the type typedef typename EraseAll  ::Result Result; }; template  struct EraseAll  , T> { // Go all the way down the list removing the type typedef Typelist  ::Result> Result; };////////////////////////////////////////////////////////////////////////////////// class template NoDuplicates// Removes all duplicate types in a typelist// Invocation (TList is a typelist):// NoDuplicates  ::Result//////////////////////////////////////////////////////////////////////////////// template  struct NoDuplicates; template <> struct NoDuplicates  { typedef NullType Result; }; template  struct NoDuplicates< Typelist  > { private: typedef typename NoDuplicates  ::Result L1; typedef typename Erase  ::Result L2; public: typedef Typelist  Result; };////////////////////////////////////////////////////////////////////////////////// class template Replace// Replaces the first occurence of a type in a typelist, with another type// Invocation (TList is a typelist, T, U are types):// Replace  ::Result// returns a typelist in which the first occurence of T is replaced with U//////////////////////////////////////////////////////////////////////////////// template  struct Replace; template  struct Replace  { typedef NullType Result; }; template  struct Replace  , T, U> { typedef Typelist  Result; }; template  struct Replace  , T, U> { typedef Typelist  ::Result> Result; };////////////////////////////////////////////////////////////////////////////////// class template ReplaceAll// Replaces all occurences of a type in a typelist, with another type// Invocation (TList is a typelist, T, U are types):// Replace  ::Result// returns a typelist in which all occurences of T is replaced with U//////////////////////////////////////////////////////////////////////////////// template  struct ReplaceAll; template  struct ReplaceAll  { typedef NullType Result; }; template  struct ReplaceAll  , T, U> { typedef Typelist  ::Result> Result; }; template  struct ReplaceAll  , T, U> { typedef Typelist  ::Result> Result; };////////////////////////////////////////////////////////////////////////////////// class template Reverse// Reverses a typelist// Invocation (TList is a typelist):// Reverse  ::Result// returns a typelist that is TList reversed//////////////////////////////////////////////////////////////////////////////// template  struct Reverse; template <> struct Reverse  { typedef NullType Result; }; template  struct Reverse< Typelist  > { typedef typename Append< typename Reverse  ::Result, Head>::Result Result; };////////////////////////////////////////////////////////////////////////////////// class template MostDerived// Finds the type in a typelist that is the most derived from a given type// Invocation (TList is a typelist, T is a type):// MostDerived  ::Result// returns the type in TList that's the most derived from T//////////////////////////////////////////////////////////////////////////////// template  struct MostDerived; template  struct MostDerived  { typedef T Result; }; template  struct MostDerived  , T> { private: typedef typename MostDerived  ::Result Candidate; public: typedef typename Select< SuperSubclass  ::value, Head, Candidate>::Result Result; };////////////////////////////////////////////////////////////////////////////////// class template DerivedToFront// Arranges the types in a typelist so that the most derived types appear first// Invocation (TList is a typelist):// DerivedToFront  ::Result// returns the reordered TList //////////////////////////////////////////////////////////////////////////////// template  struct DerivedToFront; template <> struct DerivedToFront  { typedef NullType Result; }; template  struct DerivedToFront< Typelist  > { private: typedef typename MostDerived  ::Result TheMostDerived; typedef typename Replace  ::Result Temp; typedef typename DerivedToFront  ::Result L; public: typedef Typelist  Result; }; } // namespace TL 
















Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.