bool.hh

00001 // Copyright (C) 2001, 2002, 2003  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
00027 
00028 #ifndef METALIC_BOOL_HH
00029 # define METALIC_BOOL_HH
00030 
00031 // This file defines helper structures that deal with two kinds of
00032 // booleans.
00033 //
00034 //    - classic boolean values: `true' or `false'
00035 //        These can be checked with is_true and is_false, and
00036 //        used in the `if_' type selector.
00037 //        They usually are the result of a test made in the
00038 //        argument itself.
00039 //          if_<N != 0, some_type, another_type>
00040 //
00041 //    - boolean TYPES: `true_type' or `false_type'
00042 //        As types, it's easier to use them in template, and they
00043 //        can't be confounded with integers like booleans do.
00044 
00045 namespace mlc 
00046 {  
00047 
00048   struct false_type;
00049 
00050   struct true_type  {
00051     static void is_true() {}
00052     typedef false_type not_type;
00053     typedef void is_true_type;
00054   };
00055 
00056   struct false_type {
00057     static void is_false() {}
00058     typedef true_type not_type;
00059     typedef void is_false_type;
00060   };
00061 
00062 
00063   /*----.
00064   | if_ |
00065   `----*/
00066 
00067   template <bool Cond, class if_true_type, class if_false_type>
00068   struct if_ {
00069     typedef if_true_type ret;
00070   };
00071 
00072   template<class if_true_type, class if_false_type>
00073   struct if_<false, if_true_type, if_false_type> 
00074   {
00075     typedef if_false_type ret;
00076     typedef false_type ensure_type;
00077   };
00078 
00079   /*--------.
00080   | switch_ |
00081   `--------*/
00082 
00083   struct invalid {};
00084   
00085   template<unsigned Cond, class Ret, class Cases = invalid>
00086   struct case_ {};
00087 
00088   template<unsigned Cond, class Cases, class Default = invalid>
00089   struct switch_;
00090 
00091   template<unsigned Cond, unsigned Compare, class Ret, class Default>
00092   struct switch_<Cond, case_<Compare, Ret>, Default >
00093   {
00094     typedef typename if_< (Cond == Compare), Ret, Default >::ret ret; 
00095   };
00096 
00097   template<unsigned Cond, 
00098            unsigned Compare, 
00099            class Ret, 
00100            class Cases, 
00101            class Default>
00102   struct switch_<Cond, case_<Compare, Ret, Cases>, Default > 
00103   {
00104     typedef typename 
00105       if_< (Cond == Compare), 
00106            Ret, 
00107            typename switch_<Cond, Cases, Default>::ret>::ret ret;
00108   };
00109   
00110   template<bool Cond, class Ret, class Cases = invalid>
00111   struct bool_case_ {};
00112 
00113   template<class Cases, class Default = invalid>
00114   struct bool_switch_;
00115 
00116   template<bool Cond, class Ret, class Default>
00117   struct bool_switch_<bool_case_<Cond, Ret>, Default > 
00118   {
00119     typedef typename if_< Cond, Ret, Default >::ret ret; 
00120   };
00121 
00122   template<bool Cond,class Ret, class Cases, class Default>
00123   struct bool_switch_<bool_case_<Cond, Ret, Cases>, Default > 
00124   {
00125     typedef typename 
00126       if_< Cond, 
00127            Ret, 
00128            typename bool_switch_<Cases, Default>::ret >::ret ret; 
00129   };
00130 
00131 
00132   /*-----.
00133   | misc |
00134   `-----*/
00135 
00136   template<bool> struct is_true;
00137   template<> struct is_true<true>
00138   { 
00139     static void ensure() {};
00140     typedef true_type ensure_type;
00141   };
00142 
00143   template<bool> struct is_false;
00144   template<> struct is_false<false> { static void ensure() {}; };
00145 
00146   // FIXME: find a good name for this struct.
00147 
00148   // base class for meta-types returning Boolean values
00149 
00150   template<bool> struct returns_bool_;
00151 
00152   template<>
00153   struct returns_bool_<true> : public true_type
00154   {
00155     typedef void ensure_type;
00156     static const bool ret = true;
00157     static void ensure() {}
00158   };
00159 
00160   template<>
00161   struct returns_bool_<false> : public false_type
00162   {
00163     static const bool ret = false;
00164   };
00165 
00166 } // end of namespace mlc
00167 
00168 
00169 #endif // METALIC_BOOL_HH

Generated on Thu Apr 15 20:13:06 2004 for Olena by doxygen 1.3.6-20040222