iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TypeTraits.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_TYPETRAITS_H
37 #define INCLUDE_NRT_CORE_TYPING_TYPETRAITS_H
38 
42 
43 #include <type_traits>
44 
45 namespace nrt
46 {
47  class ImageBase;
48  //! NRT type traits definition
49  /*! The struct is a convenient entry point to a variety of nrt related type traits used in metaprogramming for compile
50  time information about templated types.
51 
52  nrt_traits takes 1 or two types as arguments. The first argument is considered the primary, and traits which
53  indicate the existence of a type (eg nrt_traits<float>::is_pixel) refer to the first argument. A second argument
54  can be used of one wants to check if operators, promotions, stronger_of are defined for the two types (eg check if
55  you can promote a T=PixRGB and U=float).
56 
57  Void types can be accepted are treated like any other type. The exception is for nrt_traits<>::promote_type, which
58  will be typedef'ed to to the non-void type.
59 
60  some example:
61 
62  @code
63  using nrt;
64 
65  //returns true as its OK to add, subtract etc... PixRGb and pod-types
66  bool const t1 = nrt_traits<PixRGB<float>,int>::has_arithmetic;
67 
68  bool const t2 = nrt_traits<float>::is_pixel; //returns false;
69 
70  struct A { }:
71  bool const t3 = nrt_traits<float,A>::is_promotable; //returns false
72  //nrt_traits<float,A>::promote_type; //this will evaluate to a nrt::NotATypeError type
73  @endcode
74 
75  Note for users creating/modifying classes. The promotion mechansim relies on operator*. When the comilier is
76  trying to find an operator* that works it will first try to match for the exact type, then for any implicit
77  conversions before getting eaten up by our fail mechanism. So, if you don't indend two types to be promotable but
78  have constructors for one type that takes as an argument the other, make sure you use the 'explicit' keyword so
79  the compiler can't use the constructor to implicitly convert.
80 
81  See \link test-Traits.C \endlink for some more examples.
82 
83  \ingroup typingmisc */
84  template <class T, class U = T>
85  struct nrt_traits
86  {
87  typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type Tc;
88  typedef typename std::remove_cv<typename std::remove_reference<U>::type>::type Uc;
89 
90  /*! Access to the pixel_traits class. See PixelTraits.H The following are provided through pixel_traits:
91  - bool is_pixel
92  - size_t numChannels
93  - is_single_channel
94  - is_multi_channel
95  - has_alpha
96  - typename pod_type */
98 
99  //! check to see if we are a pixel
100  static const bool is_pixel = pixel_traits::is_pixel;
101 
102  //! check to see if we are an Image
103  static const bool is_image = std::is_base_of<ImageBase, Tc>::value;
104 
105  //! check to see if we are an arithmetic type (eg. float, int)
106  static const bool is_arithmetic = std::is_arithmetic<Tc>::value;
107 
108  //! Test for equality operators
109  /*! The following traits test wether you can use various operators with a
110  type, or with another type. All operators are symmetric (eg, test for
111  x == y and y == x) accept the has_assign_arithmetic trait.
112 
113  @{ */
114 
115  //! can we use == operator ? Returns true of Tc==Uc and Uc==Tc is defined
116  static const bool is_equality_comparable = nrt::is_equality_comparable<Tc,Uc>::value;
117 
118  //! can we use comparison operators ==,<,<=,>,>= ? Tests both Uc and Tc on the rhs and lhs of the operator
119  static const bool is_comparable = nrt::is_comparable<Tc,Uc>::value;
120 
121  //! can we use arithmetic operators +,-,*,/ ? Tests both Uc and Tt on the rhs and lhs of the operator
122  static const bool has_arithmetic = nrt::has_arithmetic<Tc,Uc>::value;
123 
124  //! can we use operators +=,-=,*=,/= ? Not symmetric, tests for Tc on lhs, Uc on the rhs only.
125  static const bool has_assign_arithmetic = nrt::has_assign_arithmetic<Tc,Uc>::value;
126 
127  /*! @} */
128 
129  /*! Convenience access to the promotion mechanism. Users can check with is_promotable to see if access to 'type'
130  will produce a valid type. */
131  struct promote : nrt::promote<Tc,Uc> { };
132 
133  /*! Convenience access to the promotion mechanism. Users can check with is_promotable to see if access to 'type'
134  will produce a valid type. This will be NotATypeError if we can't promote. */
135  typedef typename promote::type promote_type;
136 
137  //! Determine if we can promote with this type
138  static const bool is_promotable = nrt::is_promotable<Tc,Uc>::value;
139  };
140 
141  //! A type trait class to specify whether a custom class is 'trivial,' e.g., can be malloc'd
142  /*! Some of the generic container classes in NRT (Array, for example) can make decisions on how to allocate space for
143  themselves based on the type of data they are holding. They will use the most efficient methods when allocating
144  space for plain-old-data, however you can force these allocations methods for a custom class by inheriting that
145  class from nrt::trivial_type.
146 
147  \code
148  class MyCoolClass : public nrt::trivial_type
149  { ... }
150  \endcode
151 
152  \ingroup typingmisc */
153  class trivial_type { };
154 }
155 
156 #endif // INCLUDE_NRT_CORE_TYPING_TYPETRAITS_H