//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
//
//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

//  VISU OBJECT : interactive object for VISU entities implementation
//  File   : VISU_TypeList.hxx
//  Author : Oleg UVAROV
//  Module : VISU
//
#ifndef VISU_TypeList_HeaderFile
#define VISU_TypeList_HeaderFile


//----------------------------------------------------------------------------
namespace VISU
{
  //----------------------------------------------------------------------------
  namespace TL
  {
    //----------------------------------------------------------------------------
    struct TNullType {};
    

    //----------------------------------------------------------------------------
    template < class T, class U >
    struct TList
    {
      typedef T THead;
      typedef U TTail;
    };
    
    template < int v >
    struct TInt2Type
    {
      enum { value = v };
    };
    

    //----------------------------------------------------------------------------
    template < class TypeList, unsigned int index > 
    struct TTypeAt;

    template < class THead, class TTail >
    struct TTypeAt< TList< THead, TTail >, 0 >
    {
      typedef THead TResult;
    };


    template < class THead, class TTail, unsigned int index >
    struct TTypeAt< TList< THead, TTail >, index >
    {
      typedef typename TTypeAt< TTail, index - 1 >::TResult TResult;
    };


    //----------------------------------------------------------------------------
    template < class TypeList, class T > 
    struct TIndexOf;

    template < class T >
    struct TIndexOf< TNullType, T >
    {
      enum { value = -1 };
    };

    template < class T, class TTail >
    struct TIndexOf< TList< T, TTail >, T >
    {
      enum { value = 0 };
    };

    template < class THead, class TTail, class T >
    struct TIndexOf< TList< THead, TTail >, T >
    {
    private:
      enum { temp = TIndexOf< TTail, T >::value };
    public:
      enum { value = temp == -1? -1 : 1 + temp };
    };
    

    //----------------------------------------------------------------------------
    template
    <
      class T01 = TNullType, class T02 = TNullType, class T03 = TNullType, class T04 = TNullType, class T05 = TNullType,
      class T06 = TNullType, class T07 = TNullType, class T08 = TNullType, class T09 = TNullType, class T10 = TNullType,
      class T11 = TNullType, class T12 = TNullType, class T13 = TNullType, class T14 = TNullType, class T15 = TNullType,
      class T16 = TNullType, class T17 = TNullType, class T18 = TNullType, class T19 = TNullType, class T20 = TNullType,
      class T21 = TNullType, class T22 = TNullType, class T23 = TNullType, class T24 = TNullType, class T25 = TNullType,
      class T26 = TNullType, class T27 = TNullType, class T28 = TNullType, class T29 = TNullType, class T30 = TNullType,
      class T31 = TNullType, class T32 = TNullType, class T33 = TNullType, class T34 = TNullType, class T35 = TNullType,
      class T36 = TNullType, class T37 = TNullType, class T38 = TNullType, class T39 = TNullType, class T40 = TNullType
    >
    struct TSequence
    {
    private:
      typedef typename TSequence<      T02, T03, T04, T05, T06, T07, T08, T09, T10,
                                  T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
                                  T21, T22, T23, T24, T25, T26, T27, T28, T29, T30,
                                  T31, T32, T33, T34, T35, T36, T37, T38, T39, T40
                                       >::TResult 
                       TailResult;
    public:
      typedef TList< T01, TailResult > TResult;
    };
        

    //----------------------------------------------------------------------------
    template<>
    struct TSequence<>
    {
      typedef TNullType TResult;
    };


    //----------------------------------------------------------------------------
  }

  
  //----------------------------------------------------------------------------
}

#endif
