iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Promotions.H
Go to the documentation of this file.
1 /*! @file
2  @author Randolph Voorhies
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_TYPING_PROMOTIONS_H
37 #define INCLUDE_NRT_CORE_TYPING_PROMOTIONS_H
38 
42 #include <type_traits>
43 
44 namespace nrt
45 {
46  /*! \defgroup promotions Automatic type promotion for operations
47 
48  When building generic functions it is often necessary to determine the return type of a generic method which takes
49  two templated types as input. For example, what should be the return type of the following method?
50 
51  @code
52  template<class T1, class T2>
53  Dims<SOME_TYPE> operator+(Dims<T1> x, Dims<T2> y);
54  @endcode
55 
56  A good solution is to use this nrt::promote class which determines the return type by asking the compiler in which
57  type the result of T1*T2 (which is the largest data type returned by most operations) should be stored. The
58  resulting code looks like this:
59 
60  @code
61  template<class T1, class T2>
62  Dims<nrt::promote<T1,T2>::type> operator+(Dims<T1> x, Dims<T2> y);
63  @endcode
64 
65  Keep in mind that when trying to find an operator* the compiler will first try to match for the exact type, then
66  for any implicit conversions, before getting eaten up by our fail mechanism. So, if you don't indend two types to
67  be promotable but have constructors for one type that takes as an argument the other, make sure you make use of
68  the explicit keyword in your constructors so the compiler can't implicitly convert it. See
69  \link test-Traits.C \endlink
70 
71  \ingroup typing */
72 
73  /*! @{ */ // **********************************************************************
74 
75  //! Specialization of nrt::promote for when we can't promote
76  template <class T1, class T2, bool B = nrt::is_promotable<T1,T2>::value>
77  struct promote
78  {
79  typedef NotATypeError type;
80  static bool const will_promote = false;
81  };
82 
83  //! Specialization of nrt::promote for when a promotion will occur
84  template <class T1, class T2>
85  struct promote<T1,T2,true>
86  {
87  private:
88  static T1 const & x;
89  static T2 const & y;
90 
91  public:
92  //! The nrt::promote::type typedef is used to access the resulting type of the promotion
93  typedef decltype(x*y) type;
94 
95  //! Will the resulting type be a different type than the two original types?
96  static bool const will_promote = !(std::is_same<type, T1>::value && std::is_same<type, T2>::value);
97  };
98 
99  //! Specialization of nrt::promote when first type is void, promoted type is the second type
100  template <class T2>
101  struct promote<void, T2, false>
102  {
103  typedef T2 type;
104  static bool const will_promote = false;
105  };
106 
107  //! Specialization of nrt::promote when second type is void, promoted type is the first type
108  /*! This is useful if you want to not promote, for example:
109  @code
110  nrt::Image<nrt::PixGray<nrt::byte> > src;
111  nrt::Image<nrt::PixGray<nrt::byte> > dest = nrt::lowPass3<void>(src);
112  // by default, lowPass3() would return Image<PixGray<double>> as its default promo parameter is double
113  @endcode */
114  template <class T1>
115  struct promote<T1, void, false>
116  {
117  typedef T1 type;
118  static bool const will_promote = false;
119  };
120 
121  //! Specialization of nrt::promote when both types are void
122  /*! This is just to avoid compilation ambiguities in the less-specialized cases. */
123  template <>
124  struct promote<void, void, false>
125  {
126  typedef void type;
127  static bool const will_promote = false;
128  };
129 
130  /*! @} */ // **********************************************************************
131 }
132 
133 #endif // INCLUDE_NRT_CORE_TYPING_PROMOTIONS_H