global_ops_traits.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 NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH
00029 # define NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH
00030 
00031 /*
00032   Tools to determine return type of operators given the parameters
00033   types. For each type, one has to specialize the traits
00034   operator_xxx, and then use deduce_from_traits<operator_xxx, T1, T2>
00035   as return type for operatorxxx(T1, T2) functions.
00036 */
00037 
00038 # include <ntg/core/macros.hh>
00039 # include <ntg/core/type_traits.hh>
00040 
00041 # include <mlc/bool.hh>
00042 
00043 namespace ntg {
00044 
00045   namespace internal {
00046 
00047     /*-----------.
00048     | Meta tools |
00049     `-----------*/
00050 
00051     struct undefined_traits {};
00052 
00053     template <class T>
00054     struct meta_undefined_traits
00055     {
00056       typedef undefined_traits ret;
00057       typedef undefined_traits lhs_type;
00058       typedef undefined_traits rhs_type;
00059       typedef undefined_traits traits_lhs_type;
00060       typedef undefined_traits traits_rhs_type;
00061     };
00062 
00063     template <class T>
00064     struct is_defined { enum { ret = true }; };
00065     template <>
00066     struct is_defined<undefined_traits> { enum { ret = false }; };
00067 
00068     /*
00069       get_order, get_order_inv
00070 
00071       These structs are used to inverse input types (if the operator
00072       is commutative) and to specify whether input types should be
00073       converted into another type (eg. the corresponding ntg_type).
00074     */
00075 
00076     template <class T1, class T2>
00077     struct get_order
00078     {
00079       typedef T1 traits_lhs_type;
00080       typedef T2 traits_rhs_type;
00081 
00082       typedef T1 lhs_type;
00083       typedef T2 rhs_type;
00084     };
00085 
00086     template <class T1, class T2>
00087     struct get_order_inv
00088     {
00089       typedef T2 traits_lhs_type;
00090       typedef T1 traits_rhs_type;
00091 
00092       typedef T1 lhs_type;
00093       typedef T2 rhs_type;
00094     };
00095 
00096     /*---------------------------.
00097     | Operator traits definition |
00098     `---------------------------*/
00100 
00127     template <class Op, class T, class U>
00128     struct operator_traits
00129     {
00130       enum { commutative = false };
00131       typedef undefined_traits ret;
00132       typedef undefined_traits impl;
00133     };
00134 
00135     struct operator_plus {};
00136     struct operator_minus {};
00137     struct operator_times {};
00138     struct operator_div {};
00139     struct operator_mod {};
00140     struct operator_logical {};
00141     struct operator_cmp {};
00142     struct operator_min {};
00143     struct operator_max {};
00144 
00145     /*-----------------------------------.
00146     | deduce_from_traits<operator, T, U> |
00147     `-----------------------------------*/
00149 
00173     template <class Op, class T, class U>
00174     struct deduce_from_traits
00175     {
00176     private:
00177       typedef ntg_type(T) T1;
00178       typedef ntg_type(U) T2;
00179 
00180       typedef typename operator_traits<Op, T1, T2>::ret traits;
00181       typedef typename operator_traits<Op, T2, T1>::ret rev_traits;
00182 
00183       enum { can_invert = (operator_traits<Op, T2, T1>::commutative
00184                            && is_defined<rev_traits>::ret) };
00185 
00186       typedef typename
00187       mlc::if_<is_defined<traits>::ret,
00188                 get_order<T1, T2>, typename
00189                 mlc::if_<can_invert,
00190                          get_order_inv<T1, T2>,
00191                          meta_undefined_traits<undefined_traits>
00192                         >::ret
00193               >::ret deduced_type;
00194 
00195       typedef typename deduced_type::traits_lhs_type traits_lhs_type;
00196       typedef typename deduced_type::traits_rhs_type traits_rhs_type;
00197 
00198     public:
00199       typedef operator_traits<Op,
00200                               traits_lhs_type,
00201                               traits_rhs_type> deduced_traits;
00202 
00203       typedef typename deduced_type::lhs_type lhs_type;
00204       typedef typename deduced_type::rhs_type rhs_type;
00205       typedef typename deduced_traits::ret ret;
00206       typedef typename deduced_traits::impl impl;
00207     };
00208 
00209   } // end of internal.
00210 
00211 } // end of ntg.
00212 
00213 #endif // !NTG_CORE_INTERNAL_GLOBAL_OPS_TRAITS_HH

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