Amesos2 - Direct Sparse Solver Interfaces Version of the Day
Amesos2_Meta.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //           Amesos2: Templated Direct Sparse Solver Package
00006 //                  Copyright 2011 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 //
00042 // @HEADER
00043 
00058 #ifndef AMESOS2_META_HPP
00059 #define AMESOS2_META_HPP
00060 
00061 #include "Amesos2_config.h"
00062 
00063 
00064 namespace Amesos2 {
00065 
00066   namespace Meta {
00067 
00074     template <class T, T val>
00075     struct integral_constant
00076     {
00077       typedef integral_constant<T, val>  type;
00078       typedef T                          value_type;
00079       static const T value;
00080     };
00081 
00082     /* Some compilers support initializing static const members alongside the
00083      * definition, but others do not, so we go we the safe method of external
00084      * initialization.
00085      */
00086     template <class T, T val>
00087     const T integral_constant<T,val>::value = val;
00088 
00089     typedef integral_constant<bool, true>  true_type;
00090     typedef integral_constant<bool, false> false_type;
00091 
00093     // Testing the same'ness of two types //
00095 
00099     template <typename, typename>
00100     struct is_same : public false_type
00101     {};
00102 
00103     template <typename T>
00104     struct is_same<T,T> : public true_type
00105     {};
00106 
00107 
00108 
00110     // Meta-functions for boolean operators //
00112 
00113     /* Must define these with the '_' suffix because they are
00114      * otherwise keywords in C++
00115      */
00116 
00117     template <bool b1, bool b2>
00118     struct or_ : public false_type {};
00119 
00120     template <bool b>
00121     struct or_<true,b> : public true_type {};
00122 
00123     template <bool b>
00124     struct or_<b,true> : public true_type {};
00125 
00126 
00127     template <bool b1, bool b2>
00128     struct and_ : public false_type {};
00129 
00130     template <>
00131     struct and_<true,true> : public true_type {};
00132 
00133 
00134     template <bool b>
00135     struct not_ {};
00136 
00137     template <>
00138     struct not_<true> : false_type {};
00139 
00140     template <>
00141     struct not_<false> : true_type {};
00142 
00143 
00145     // Evaluating to a conditional type //
00147 
00148     template <bool B, typename T1, typename T2>
00149     struct if_then_else {};
00150 
00151     template <typename T1, typename T2>
00152     struct if_then_else<true, T1, T2> {
00153       typedef T1 type;
00154     };
00155 
00156     template <typename T1, typename T2>
00157     struct if_then_else<false, T1, T2> {
00158       typedef T2 type;
00159     };
00160 
00161 
00163     // A meta-programming type-list structure //
00165 
00166     struct nil_t {};                // to denote an empty list
00167 
00168     template <typename Head, typename Tail>
00169     struct type_list {
00170       typedef type_list<Head,Tail> type;
00171       typedef Head head;
00172       typedef Tail tail;
00173     };
00174 
00186     template <typename T1>
00187     struct make_list1
00188       : type_list<T1,nil_t>
00189     { };
00190 
00191     template <typename T1, typename T2>
00192     struct make_list2
00193       : type_list<T1,type_list<T2,nil_t> >
00194     { };
00195 
00196     template <typename T1, typename T2, typename T3>
00197     struct make_list3
00198       : type_list<T1, type_list<T2, type_list<T3,nil_t> > >
00199     { };
00200 
00201     template <typename T1, typename T2, typename T3, typename T4>
00202     struct make_list4
00203       : type_list<T1, type_list<T2, type_list<T3, type_list<T4,nil_t> > > >
00204     { };
00205 
00206     template <typename T1, typename T2, typename T3, typename T4, typename T5>
00207     struct make_list5
00208       : type_list<T1, type_list<T2, type_list<T3, type_list<T4, type_list<T5,nil_t> > > > >
00209     { };
00210 
00211     template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00212     struct make_list6
00213       : type_list<T1, type_list<T2, type_list<T3, type_list<T4, type_list<T5, type_list<T6,nil_t> > > > > >
00214     { };
00215 
00216     /* More declarations for larger type lists may be added if necessary */
00217 
00218 
00231     template <typename list, typename elem>
00232     struct type_list_contains {
00233       static const bool value;
00234     };
00235 
00236     // Base recursive case
00237     template <typename elem>
00238     struct type_list_contains<nil_t,elem> {
00239       static const bool value = false;
00240     };
00241 
00242     template <typename list, typename elem>
00243     const bool type_list_contains<list,elem>::value
00244     = if_then_else<is_same<typename list::head, elem>::value,
00245                    true_type,
00246                    type_list_contains<typename list::tail,elem> >::type::value;
00247 
00250   } // end namespace Meta
00251 
00252 } // end namespace Amesos2
00253 
00254 #endif  // AMESOS2_META_HPP