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     /* SR: We will not use external initialization for the static const types.
00075      * Combined with template meta programming this fails in Intel compilers
00076      * 11-13. Moving all the initializations inside the declarations.
00077      */
00078     template <class T, T val>
00079     struct integral_constant
00080     {
00081       typedef integral_constant<T, val>  type;
00082       typedef T                          value_type;
00083       static const T value = val;
00084     };
00085 
00086 
00087     typedef integral_constant<bool, true>  true_type;
00088     typedef integral_constant<bool, false> false_type;
00089 
00091     // Testing the same'ness of two types //
00093 
00097     template <typename, typename>
00098     struct is_same : public false_type
00099     {};
00100 
00101     template <typename T>
00102     struct is_same<T,T> : public true_type
00103     {};
00104 
00105 
00106 
00108     // Meta-functions for boolean operators //
00110 
00111     /* Must define these with the '_' suffix because they are
00112      * otherwise keywords in C++
00113      */
00114 
00115     template <bool b1, bool b2>
00116     struct or_ : public false_type {};
00117 
00118     template <bool b>
00119     struct or_<true,b> : public true_type {};
00120 
00121     template <bool b>
00122     struct or_<b,true> : public true_type {};
00123 
00124 
00125     template <bool b1, bool b2>
00126     struct and_ : public false_type {};
00127 
00128     template <>
00129     struct and_<true,true> : public true_type {};
00130 
00131 
00132     template <bool b>
00133     struct not_ {};
00134 
00135     template <>
00136     struct not_<true> : false_type {};
00137 
00138     template <>
00139     struct not_<false> : true_type {};
00140 
00141 
00143     // Evaluating to a conditional type //
00145 
00146     template <bool B, typename T1, typename T2>
00147     struct if_then_else {};
00148 
00149     template <typename T1, typename T2>
00150     struct if_then_else<true, T1, T2> {
00151       typedef T1 type;
00152     };
00153 
00154     template <typename T1, typename T2>
00155     struct if_then_else<false, T1, T2> {
00156       typedef T2 type;
00157     };
00158 
00159 
00161     // A meta-programming type-list structure //
00163 
00164     struct nil_t {};                // to denote an empty list
00165 
00166     template <typename Head, typename Tail>
00167     struct type_list {
00168       typedef type_list<Head,Tail> type;
00169       typedef Head head;
00170       typedef Tail tail;
00171     };
00172 
00184     template <typename T1>
00185     struct make_list1
00186       : type_list<T1,nil_t>
00187     { };
00188 
00189     template <typename T1, typename T2>
00190     struct make_list2
00191       : type_list<T1,type_list<T2,nil_t> >
00192     { };
00193 
00194     template <typename T1, typename T2, typename T3>
00195     struct make_list3
00196       : type_list<T1, type_list<T2, type_list<T3,nil_t> > >
00197     { };
00198 
00199     template <typename T1, typename T2, typename T3, typename T4>
00200     struct make_list4
00201       : type_list<T1, type_list<T2, type_list<T3, type_list<T4,nil_t> > > >
00202     { };
00203 
00204     template <typename T1, typename T2, typename T3, typename T4, typename T5>
00205     struct make_list5
00206       : type_list<T1, type_list<T2, type_list<T3, type_list<T4, type_list<T5,nil_t> > > > >
00207     { };
00208 
00209     template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
00210     struct make_list6
00211       : type_list<T1, type_list<T2, type_list<T3, type_list<T4, type_list<T5, type_list<T6,nil_t> > > > > >
00212     { };
00213 
00214     /* More declarations for larger type lists may be added if necessary */
00215 
00216 
00230     /* SR: We will not use external initialization for the static const types.
00231      * Combined with template meta programming this fails in Intel compilers
00232      * 11-13. Moving all the initializations inside the declarations.
00233      */
00234     template <typename list, typename elem>
00235     struct type_list_contains {
00236       static const bool value =
00237                    if_then_else<is_same<typename list::head, elem>::value,
00238                    true_type,
00239                    type_list_contains<typename list::tail,elem> >::type::value;
00240     };
00241 
00242     // Base recursive case
00243     template <typename elem>
00244     struct type_list_contains<nil_t,elem> {
00245       static const bool value = false;
00246     };
00247 
00250   } // end namespace Meta
00251 
00252 } // end namespace Amesos2
00253 
00254 #endif  // AMESOS2_META_HPP