/** * Tencent is pleased to support the open source community by making Tars available. * * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ #ifndef _TARS_TYPE_LIST_H_ #define _TARS_TYPE_LIST_H_ namespace tars { namespace tl { template struct TypeList {}; // get the Nth type in a given type list. template struct TypeAtImpl; template struct TypeAtImpl > : TypeAtImpl > {}; template struct TypeAtImpl<0, TypeList > { using Type = T; }; // throw error while empty list. template <> struct TypeAtImpl<0, TypeList<> > {}; template using TypeAt = typename TypeAtImpl >::Type; // index of a type in a given type list. template struct IndexOfImpl; template struct IndexOfImpl > { enum { value = -1 }; }; template struct IndexOfImpl > { enum { value = 0 }; }; template struct IndexOfImpl > { private: enum { temp = IndexOfImpl >::value }; public: enum { value = ((temp == -1) ? -1 : (1 + temp)) }; }; template using IndexOf = IndexOfImpl; // drop first N types in a given type list. template struct DropTypeListItemImpl; template struct DropTypeListItemImpl > : DropTypeListItemImpl > {}; template struct DropTypeListItemImpl<0, TypeList > { using Type = TypeList; }; template <> struct DropTypeListItemImpl<0, TypeList<> > { using Type = TypeList<>; }; template using DropTypeListItem = typename DropTypeListItemImpl::Type; // take first N types in a given type list. template struct TakeTypeListItemImpl; template struct TakeTypeListItemImpl, TList...> : TakeTypeListItemImpl, TList..., T> {}; template struct TakeTypeListItemImpl<0, TypeList, TList...> { using Type = TypeList; }; template struct TakeTypeListItemImpl<0, TypeList<>, TList...> { using Type = TypeList; }; template using TakeTypeListItem = typename TakeTypeListItemImpl::Type; // concat type lists. template struct ConcatTypeListImpl; template struct ConcatTypeListImpl, TypeList > { using Type = TypeList; }; template using ConcatTypeList = typename ConcatTypeListImpl::Type; } // end namespace tl(type list) } // end namespace tars #endif