Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // -*- C++ -*-
  2.  
  3. // Copyright (C) 2005-2015 Free Software Foundation, Inc.
  4. //
  5. // This file is part of the GNU ISO C++ Library.  This library is free
  6. // software; you can redistribute it and/or modify it under the
  7. // terms of the GNU General Public License as published by the
  8. // Free Software Foundation; either version 3, or (at your option)
  9. // any later version.
  10.  
  11. // This library is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. // GNU General Public License for more details.
  15.  
  16. // Under Section 7 of GPL version 3, you are granted additional
  17. // permissions described in the GCC Runtime Library Exception, version
  18. // 3.1, as published by the Free Software Foundation.
  19.  
  20. // You should have received a copy of the GNU General Public License and
  21. // a copy of the GCC Runtime Library Exception along with this program;
  22. // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23. // <http://www.gnu.org/licenses/>.
  24.  
  25. // Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
  26.  
  27. // Permission to use, copy, modify, sell, and distribute this software
  28. // is hereby granted without fee, provided that the above copyright
  29. // notice appears in all copies, and that both that copyright notice and
  30. // this permission notice appear in supporting documentation. None of
  31. // the above authors, nor IBM Haifa Research Laboratories, make any
  32. // representation about the suitability of this software for any
  33. // purpose. It is provided "as is" without express or implied warranty.
  34.  
  35. /**
  36.  *  @file ext/typelist.h
  37.  *  This file is a GNU extension to the Standard C++ Library.
  38.  *
  39.  *  Contains typelist_chain definitions.
  40.  *  Typelists are an idea by Andrei Alexandrescu.
  41.  */
  42.  
  43. #ifndef _TYPELIST_H
  44. #define _TYPELIST_H 1
  45.  
  46. #include <ext/type_traits.h>
  47.  
  48. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  49. {
  50. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  51.  
  52. /** @namespace __gnu_cxx::typelist
  53.  *  @brief GNU typelist extensions for public compile-time use.
  54. */
  55. namespace typelist
  56. {
  57.   struct null_type { };
  58.  
  59.   template<typename Root>
  60.     struct node
  61.     {
  62.       typedef Root      root;
  63.     };
  64.  
  65.   // Forward declarations of functors.
  66.   template<typename Hd, typename Typelist>
  67.     struct chain
  68.     {
  69.       typedef Hd        head;
  70.       typedef Typelist  tail;
  71.     };
  72.  
  73.   // Apply all typelist types to unary functor.
  74.   template<typename Fn, typename Typelist>
  75.     void
  76.     apply(Fn&, Typelist);
  77.  
  78.   /// Apply all typelist types to generator functor.
  79.   template<typename Gn, typename Typelist>
  80.     void
  81.     apply_generator(Gn&, Typelist);
  82.  
  83.   // Apply all typelist types and values to generator functor.
  84.   template<typename Gn, typename TypelistT, typename TypelistV>
  85.     void
  86.     apply_generator(Gn&, TypelistT, TypelistV);
  87.  
  88.   template<typename Typelist0, typename Typelist1>
  89.     struct append;
  90.  
  91.   template<typename Typelist_Typelist>
  92.     struct append_typelist;
  93.  
  94.   template<typename Typelist, typename T>
  95.     struct contains;
  96.  
  97.   template<typename Typelist, template<typename T> class Pred>
  98.     struct filter;
  99.  
  100.   template<typename Typelist, int i>
  101.     struct at_index;
  102.  
  103.   template<typename Typelist, template<typename T> class Transform>
  104.     struct transform;
  105.  
  106.   template<typename Typelist_Typelist>
  107.     struct flatten;
  108.  
  109.   template<typename Typelist>
  110.     struct from_first;
  111.  
  112.   template<typename T1>
  113.     struct create1;
  114.  
  115.   template<typename T1, typename T2>
  116.     struct create2;
  117.  
  118.   template<typename T1, typename T2, typename T3>
  119.     struct create3;
  120.  
  121.   template<typename T1, typename T2, typename T3, typename T4>
  122.     struct create4;
  123.  
  124.   template<typename T1, typename T2, typename T3, typename T4, typename T5>
  125.     struct create5;
  126.  
  127.   template<typename T1, typename T2, typename T3,
  128.            typename T4, typename T5, typename T6>
  129.     struct create6;
  130. } // namespace typelist
  131.  
  132. _GLIBCXX_END_NAMESPACE_VERSION
  133. } // namespace
  134.  
  135.  
  136. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  137. {
  138. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  139.  
  140. namespace typelist
  141. {
  142. namespace detail
  143. {
  144.   template<typename Fn, typename Typelist_Chain>
  145.     struct apply_;
  146.  
  147.   template<typename Fn, typename Hd, typename Tl>
  148.     struct apply_<Fn, chain<Hd, Tl> >
  149.     {
  150.       void
  151.       operator()(Fn& f)
  152.       {
  153.         f.operator()(Hd());
  154.         apply_<Fn, Tl> next;
  155.         next(f);
  156.       }
  157.     };
  158.  
  159.   template<typename Fn>
  160.     struct apply_<Fn, null_type>
  161.     {
  162.       void
  163.       operator()(Fn&) { }
  164.     };
  165.  
  166.   template<typename Gn, typename Typelist_Chain>
  167.     struct apply_generator1_;
  168.  
  169.   template<typename Gn, typename Hd, typename Tl>
  170.     struct apply_generator1_<Gn, chain<Hd, Tl> >
  171.     {
  172.       void
  173.       operator()(Gn& g)
  174.       {
  175.         g.template operator()<Hd>();
  176.         apply_generator1_<Gn, Tl> next;
  177.         next(g);
  178.       }
  179.     };
  180.  
  181.   template<typename Gn>
  182.     struct apply_generator1_<Gn, null_type>
  183.     {
  184.       void
  185.       operator()(Gn&) { }
  186.     };
  187.  
  188.   template<typename Gn, typename TypelistT_Chain, typename TypelistV_Chain>
  189.     struct apply_generator2_;
  190.  
  191.   template<typename Gn, typename Hd1, typename TlT, typename Hd2, typename TlV>
  192.     struct apply_generator2_<Gn, chain<Hd1, TlT>, chain<Hd2, TlV> >
  193.     {
  194.       void
  195.       operator()(Gn& g)
  196.       {
  197.         g.template operator()<Hd1, Hd2>();
  198.         apply_generator2_<Gn, TlT, TlV> next;
  199.         next(g);
  200.       }
  201.     };
  202.  
  203.   template<typename Gn>
  204.     struct apply_generator2_<Gn, null_type, null_type>
  205.     {
  206.       void
  207.       operator()(Gn&) { }
  208.     };
  209.  
  210.   template<typename Typelist_Chain0, typename Typelist_Chain1>
  211.     struct append_;
  212.  
  213.   template<typename Hd, typename Tl, typename Typelist_Chain>
  214.     struct append_<chain<Hd, Tl>, Typelist_Chain>
  215.     {
  216.     private:
  217.       typedef append_<Tl, Typelist_Chain>                       append_type;
  218.  
  219.     public:
  220.       typedef chain<Hd, typename append_type::type>             type;
  221.     };
  222.  
  223.   template<typename Typelist_Chain>
  224.     struct append_<null_type, Typelist_Chain>
  225.     {
  226.       typedef Typelist_Chain                                    type;
  227.     };
  228.  
  229.   template<typename Typelist_Chain>
  230.     struct append_<Typelist_Chain, null_type>
  231.     {
  232.       typedef Typelist_Chain                                    type;
  233.     };
  234.  
  235.   template<>
  236.     struct append_<null_type, null_type>
  237.     {
  238.       typedef null_type                                         type;
  239.     };
  240.  
  241.   template<typename Typelist_Typelist_Chain>
  242.     struct append_typelist_;
  243.  
  244.   template<typename Hd>
  245.     struct append_typelist_<chain<Hd, null_type> >
  246.     {
  247.       typedef chain<Hd, null_type>                              type;
  248.     };
  249.  
  250.   template<typename Hd, typename Tl>
  251.     struct append_typelist_<chain< Hd, Tl> >
  252.     {
  253.     private:
  254.       typedef typename append_typelist_<Tl>::type               rest_type;
  255.  
  256.     public:
  257.       typedef typename append<Hd, node<rest_type> >::type::root type;
  258.     };
  259.  
  260.   template<typename Typelist_Chain, typename T>
  261.     struct contains_;
  262.  
  263.   template<typename T>
  264.     struct contains_<null_type, T>
  265.     {
  266.       enum
  267.         {
  268.           value = false
  269.         };
  270.     };
  271.  
  272.   template<typename Hd, typename Tl, typename T>
  273.     struct contains_<chain<Hd, Tl>, T>
  274.     {
  275.       enum
  276.         {
  277.           value = contains_<Tl, T>::value
  278.         };
  279.     };
  280.  
  281.   template<typename Tl, typename T>
  282.     struct contains_<chain<T, Tl>, T>
  283.     {
  284.       enum
  285.         {
  286.           value = true
  287.         };
  288.     };
  289.  
  290.   template<typename Typelist_Chain, template<typename T> class Pred>
  291.     struct chain_filter_;
  292.  
  293.   template<template<typename T> class Pred>
  294.     struct chain_filter_<null_type, Pred>
  295.     {
  296.       typedef null_type                                         type;
  297.   };
  298.  
  299.   template<typename Hd, typename Tl, template<typename T> class Pred>
  300.     struct chain_filter_<chain<Hd, Tl>, Pred>
  301.     {
  302.     private:
  303.       enum
  304.         {
  305.           include_hd = Pred<Hd>::value
  306.         };
  307.  
  308.       typedef typename chain_filter_<Tl, Pred>::type            rest_type;
  309.       typedef chain<Hd, rest_type>                              chain_type;
  310.  
  311.     public:
  312.       typedef typename __conditional_type<include_hd, chain_type, rest_type>::__type type;
  313.   };
  314.  
  315.   template<typename Typelist_Chain, int i>
  316.     struct chain_at_index_;
  317.  
  318.   template<typename Hd, typename Tl>
  319.     struct chain_at_index_<chain<Hd, Tl>, 0>
  320.     {
  321.       typedef Hd                                                type;
  322.     };
  323.  
  324.   template<typename Hd, typename Tl, int i>
  325.     struct chain_at_index_<chain<Hd, Tl>, i>
  326.     {
  327.       typedef typename chain_at_index_<Tl, i - 1>::type         type;
  328.     };
  329.  
  330.   template<class Typelist_Chain, template<typename T> class Transform>
  331.     struct chain_transform_;
  332.  
  333.   template<template<typename T> class Transform>
  334.     struct chain_transform_<null_type, Transform>
  335.     {
  336.       typedef null_type                                         type;
  337.     };
  338.  
  339.   template<class Hd, class Tl, template<typename T> class Transform>
  340.     struct chain_transform_<chain<Hd, Tl>, Transform>
  341.     {
  342.     private:
  343.       typedef typename chain_transform_<Tl, Transform>::type    rest_type;
  344.       typedef typename Transform<Hd>::type                      transform_type;
  345.  
  346.     public:
  347.       typedef chain<transform_type, rest_type>                  type;
  348.     };
  349.  
  350.   template<typename Typelist_Typelist_Chain>
  351.     struct chain_flatten_;
  352.  
  353.   template<typename Hd_Tl>
  354.     struct chain_flatten_<chain<Hd_Tl, null_type> >
  355.     {
  356.       typedef typename Hd_Tl::root                              type;
  357.     };
  358.  
  359.   template<typename Hd_Typelist, class Tl_Typelist>
  360.     struct chain_flatten_<chain<Hd_Typelist, Tl_Typelist> >
  361.     {
  362.     private:
  363.       typedef typename chain_flatten_<Tl_Typelist>::type        rest_type;
  364.       typedef append<Hd_Typelist, node<rest_type> >             append_type;
  365.     public:
  366.       typedef typename append_type::type::root                  type;
  367.     };
  368. } // namespace detail
  369. } // namespace typelist
  370.  
  371. _GLIBCXX_END_NAMESPACE_VERSION
  372. } // namespace
  373.  
  374. #define _GLIBCXX_TYPELIST_CHAIN1(X0) __gnu_cxx::typelist::chain<X0, __gnu_cxx::typelist::null_type>
  375. #define _GLIBCXX_TYPELIST_CHAIN2(X0, X1) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN1(X1) >
  376. #define _GLIBCXX_TYPELIST_CHAIN3(X0, X1, X2) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN2(X1, X2) >
  377. #define _GLIBCXX_TYPELIST_CHAIN4(X0, X1, X2, X3) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN3(X1, X2, X3) >
  378. #define _GLIBCXX_TYPELIST_CHAIN5(X0, X1, X2, X3, X4) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN4(X1, X2, X3, X4) >
  379. #define _GLIBCXX_TYPELIST_CHAIN6(X0, X1, X2, X3, X4, X5) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN5(X1, X2, X3, X4, X5) >
  380. #define _GLIBCXX_TYPELIST_CHAIN7(X0, X1, X2, X3, X4, X5, X6) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN6(X1, X2, X3, X4, X5, X6) >
  381. #define _GLIBCXX_TYPELIST_CHAIN8(X0, X1, X2, X3, X4, X5, X6, X7) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN7(X1, X2, X3, X4, X5, X6, X7) >
  382. #define _GLIBCXX_TYPELIST_CHAIN9(X0, X1, X2, X3, X4, X5, X6, X7, X8) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN8(X1, X2, X3, X4, X5, X6, X7, X8) >
  383. #define _GLIBCXX_TYPELIST_CHAIN10(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN9(X1, X2, X3, X4, X5, X6, X7, X8, X9) >
  384. #define _GLIBCXX_TYPELIST_CHAIN11(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN10(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10) >
  385. #define _GLIBCXX_TYPELIST_CHAIN12(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN11(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11) >
  386. #define _GLIBCXX_TYPELIST_CHAIN13(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN12(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12) >
  387. #define _GLIBCXX_TYPELIST_CHAIN14(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN13(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13) >
  388. #define _GLIBCXX_TYPELIST_CHAIN15(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN14(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14) >
  389. #define _GLIBCXX_TYPELIST_CHAIN16(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN15(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15) >
  390. #define _GLIBCXX_TYPELIST_CHAIN17(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN16(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16) >
  391. #define _GLIBCXX_TYPELIST_CHAIN18(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN17(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17) >
  392. #define _GLIBCXX_TYPELIST_CHAIN19(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN18(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18) >
  393. #define _GLIBCXX_TYPELIST_CHAIN20(X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) __gnu_cxx::typelist::chain<X0, _GLIBCXX_TYPELIST_CHAIN19(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19) >
  394.  
  395. namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
  396. {
  397. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  398.  
  399. namespace typelist
  400. {
  401.   template<typename Fn, typename Typelist>
  402.     void
  403.     apply(Fn& fn, Typelist)
  404.     {
  405.       detail::apply_<Fn, typename Typelist::root> a;
  406.       a(fn);
  407.     }
  408.  
  409.   template<typename Fn, typename Typelist>
  410.     void
  411.     apply_generator(Fn& fn, Typelist)
  412.     {
  413.       detail::apply_generator1_<Fn, typename Typelist::root> a;
  414.       a(fn);
  415.     }
  416.  
  417.   template<typename Fn, typename TypelistT, typename TypelistV>
  418.     void
  419.     apply_generator(Fn& fn, TypelistT, TypelistV)
  420.     {
  421.       typedef typename TypelistT::root rootT;
  422.       typedef typename TypelistV::root rootV;
  423.       detail::apply_generator2_<Fn, rootT, rootV> a;
  424.       a(fn);
  425.     }
  426.  
  427.   template<typename Typelist0, typename Typelist1>
  428.     struct append
  429.     {
  430.     private:
  431.       typedef typename Typelist0::root                          root0_type;
  432.       typedef typename Typelist1::root                          root1_type;
  433.       typedef detail::append_<root0_type, root1_type>           append_type;
  434.  
  435.     public:
  436.       typedef node<typename append_type::type>                  type;
  437.     };
  438.  
  439.   template<typename Typelist_Typelist>
  440.     struct append_typelist
  441.     {
  442.     private:
  443.       typedef typename Typelist_Typelist::root                  root_type;
  444.       typedef detail::append_typelist_<root_type>               append_type;
  445.  
  446.     public:
  447.       typedef node<typename append_type::type>                  type;
  448.     };
  449.  
  450.   template<typename Typelist, typename T>
  451.     struct contains
  452.     {
  453.     private:
  454.       typedef typename Typelist::root                           root_type;
  455.  
  456.     public:
  457.       enum
  458.         {
  459.           value = detail::contains_<root_type, T>::value
  460.         };
  461.     };
  462.  
  463.   template<typename Typelist, template<typename T> class Pred>
  464.     struct filter
  465.     {
  466.     private:
  467.       typedef typename Typelist::root                           root_type;
  468.       typedef detail::chain_filter_<root_type, Pred>            filter_type;
  469.  
  470.     public:
  471.       typedef node<typename filter_type::type>                  type;
  472.     };
  473.  
  474.   template<typename Typelist, int i>
  475.     struct at_index
  476.     {
  477.     private:
  478.       typedef typename Typelist::root                           root_type;
  479.       typedef detail::chain_at_index_<root_type, i>             index_type;
  480.  
  481.     public:
  482.       typedef typename index_type::type                         type;
  483.     };
  484.  
  485.   template<typename Typelist, template<typename T> class Transform>
  486.     struct transform
  487.     {
  488.     private:
  489.       typedef typename Typelist::root                           root_type;
  490.       typedef detail::chain_transform_<root_type, Transform>    transform_type;
  491.  
  492.     public:
  493.       typedef node<typename transform_type::type>               type;
  494.     };
  495.  
  496.   template<typename Typelist_Typelist>
  497.     struct flatten
  498.     {
  499.     private:
  500.       typedef typename Typelist_Typelist::root                  root_type;
  501.       typedef typename detail::chain_flatten_<root_type>::type  flatten_type;
  502.  
  503.     public:
  504.       typedef node<flatten_type>                                type;
  505.     };
  506.  
  507.   template<typename Typelist>
  508.     struct from_first
  509.     {
  510.     private:
  511.       typedef typename at_index<Typelist, 0>::type              first_type;
  512.  
  513.     public:
  514.       typedef node<chain<first_type, null_type> >               type;
  515.     };
  516.  
  517.   template<typename T1>
  518.     struct create1
  519.     {
  520.       typedef node<_GLIBCXX_TYPELIST_CHAIN1(T1)>                type;
  521.     };
  522.  
  523.   template<typename T1, typename T2>
  524.     struct create2
  525.     {
  526.       typedef node<_GLIBCXX_TYPELIST_CHAIN2(T1,T2)>             type;
  527.     };
  528.  
  529.   template<typename T1, typename T2, typename T3>
  530.     struct create3
  531.     {
  532.       typedef node<_GLIBCXX_TYPELIST_CHAIN3(T1,T2,T3)>          type;
  533.     };
  534.  
  535.   template<typename T1, typename T2, typename T3, typename T4>
  536.     struct create4
  537.     {
  538.       typedef node<_GLIBCXX_TYPELIST_CHAIN4(T1,T2,T3,T4)>       type;
  539.     };
  540.  
  541.   template<typename T1, typename T2, typename T3,
  542.            typename T4, typename T5>
  543.     struct create5
  544.     {
  545.       typedef node<_GLIBCXX_TYPELIST_CHAIN5(T1,T2,T3,T4,T5)>    type;
  546.     };
  547.  
  548.   template<typename T1, typename T2, typename T3,
  549.            typename T4, typename T5, typename T6>
  550.     struct create6
  551.     {
  552.       typedef node<_GLIBCXX_TYPELIST_CHAIN6(T1,T2,T3,T4,T5,T6)> type;
  553.     };
  554. } // namespace typelist
  555. _GLIBCXX_END_NAMESPACE_VERSION
  556. } // namespace
  557.  
  558.  
  559. #endif
  560.