JASPL  0.2
Just Another Signal Processing Library
jtypetraits.h
1 #ifndef JTYPETRAITS_H
2 #define JTYPETRAITS_H
3 
4 // C System-Headers
5 #include <stdio.h>
6 // C++ System headers
7 #include <type_traits>
8 #include <string>
9 #include <assert.h> //static_assert
10 #include <iostream>
11 #include <fstream>
12 #include <typeinfo> // typeid, typeof
13 #include <cxxabi.h>// abi::__cxa_demangle
14 //OpenCL Headers
15 #include <CL/cl.h>
16 #include <CL/cl.hpp>
17 // Boost Headers
18 #include <boost/lexical_cast.hpp>
19 #include <boost/filesystem.hpp>
20 // Miscellaneous Headers
21 //
22 
23 #define\
24  SOURCE_FILE \
25 ({\
26  std::ifstream file_stream(__FILE__);\
27  std::stringstream buffer;\
28  buffer << file_stream.rdbuf();\
29  buffer.str();\
30 })\
31 
32 #define\
33  SOURCE_DIR \
34 ({\
35  std::string current_path = __FILE__;\
36  boost::filesystem::path p( current_path );\
37  boost::filesystem::path dir = p.parent_path();\
38  auto full_path = boost::filesystem::canonical( dir );\
39  full_path.string();\
40 })\
41 
42 #define\
43  __CLASS__ \
44 ({\
45  abi::__cxa_demangle(typeid(*this).name(), 0, 0, NULL);\
46 })\
47 
48 /*
49 #define\
50  OCL_DEBUG(err) \
51 ({\
52  if( debug ){\
53  std::cout << __func__ <<" OpenCL Status: " << jaspl::ocl::CLErrorToString( err ) << std::endl;\
54  }\
55 })\
56 */
57 
58 //#ifdef QT_DEBUG
59 //#define DEBUG_ON 1
60 //#else
61 //#define DEBUG_ON 0
62 //#endif
63 
64 #ifdef DEBUG
65 #define DEBUG_ON 1
66 #else
67 #define DEBUG_ON 0
68 #endif
69 
70 #ifdef NDEBUG
71 #define NDEBUG_ON 1
72 #else
73 #define NDEBUG_ON 0
74 #endif
75 
76 #define OCL_DEBUG(err, ...) \
77  do { if (DEBUG_ON) std::cout << __func__ <<\
78  __FILE__ <<\
79  " Line# "<<\
80  __LINE__ <<\
81  " OpenCL Status: " <<\
82  jaspl::ocl::CLErrorToString( err ) << std::endl; } while (0)
83 
84 
85 namespace jaspl {
86 
87 //Get the name of a type as it would appear in source code
88 template <typename T> std::string get_type_name () {
89  int status;
90  char* type_name = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
91  std::string type_str = std::string( type_name );
92 
93  free (type_name);
94 
95  return type_str;
96 }
97 
98 //Get the name of a type as it would appear in source code
99 template <typename T> std::string get_type_name ( T& to_check ) {
100  int status;
101  char* type_name = abi::__cxa_demangle(typeid(*to_check).name(), 0, 0, &status);
102  std::string type_str = std::string( type_name );
103 
104  free (type_name);
105 
106  return type_str;
107 }
108 
109 //Check if given type is a numerical type
110 template <typename T> void check_if_arithmetic() {
111  if ( !std::is_arithmetic<T>::value ) {
112 
113  std::string err_mesg = __FUNCTION__;
114  err_mesg += "cannot initialize from non-arithmetic type ";
115  err_mesg += get_type_name<T>();
116  throw std::invalid_argument(err_mesg);
117  }
118 }
119 
120 
121 
122 // SFINAE test for [] operator
123 template <typename T>
125  typedef char one;
126  typedef long two;
127 
128  template <typename C> static one test( __typeof__(&C::operator[]) ) ;
129 // template <typename C> static one test(decltype(&C::operator[])*) ;
130  template <typename C> static two test(...);
131 
132  public:
133  enum { value = sizeof(test<T>(0)) == sizeof(char) };
134 };
135 
136 // SFINAE test for data()
137 template <typename T>
138 class has_data {
139  typedef char one;
140  typedef long two;
141 
142 // template <typename C> static one test( __typeof__(&C::data) ) ;
143  template <typename C> static one test(decltype(&C::data)*) ;
144  template <typename C> static two test(...);
145 
146  public:
147  enum { value = sizeof(test<T>(0)) == sizeof(char) };
148 };
149 
150 // SFINAE test for size()
151 template <typename T>
152 class has_size {
153  typedef char one;
154  typedef long two;
155 
156 // template <typename C> static one test( __typeof__(&C::size) ) ;
157  template <typename C> static one test(decltype(&C::size)*) ;
158  template <typename C> static two test(...);
159 
160  public:
161  enum { value = sizeof(test<T>(0)) == sizeof(char) };
162 };
163 
164 //Check for data() method, even if it is overloaded
165 template <typename T, typename... Args>
166 class has_data2 {
167  template <typename C,typename = decltype( std::declval<C>().data (std::declval<Args>()...) )>
168  static std::true_type test(int);
169  template <typename C>
170  static std::false_type test(...);
171 
172  public:
173  static constexpr bool value = decltype(test<T>(0))::value;
174 
175 };
176 
177 //Part of cxx-prettyprint by Louis Delacroix @https://github.com/louisdx/cxx-prettyprint
178 
179 template<typename T>
181  private:
182  typedef char yes;
183  typedef struct {
184  char array[2];
185  } no;
186 
187  template<typename C> static yes test(typename C::const_iterator*);
188  template<typename C> static no test(...);
189  public:
190  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
191  typedef T type;
192 };
193 
194 template <typename T>
196  template<typename C> static char (&f(typename std::enable_if<
197  std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::begin)),
198  typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
199 
200  template<typename C> static char (&f(...))[2];
201 
202  template<typename C> static char (&g(typename std::enable_if<
203  std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::end)),
204  typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
205 
206  template<typename C> static char (&g(...))[2];
207 
208  static bool const beg_value = sizeof(f<T>(0)) == 1;
209  static bool const end_value = sizeof(g<T>(0)) == 1;
210 };
211 
212 //End cxx-prettyprint by Louis Delacroix @https://github.com/louisdx/cxx-prettyprint
213 
214 template <typename T>
216 
217  enum { value = has_const_iterator<T>::value &&\
218  has_begin_end<T>::beg_value &&\
219  has_begin_end<T>::end_value &&\
220  has_size<T>::value
221  };
222 };
223 
224 //Check a class for the [] operator
225 template <typename T> void check_for_accesor ( T& to_check ) {
226 
227  if( !has_accessor< T >::value ) {
228  std::string err_mesg = __func__;
229  err_mesg += "\nType ";
230  err_mesg += get_type_name<T>();
231  err_mesg += " lacks accessor operator, []";
232  throw std::invalid_argument(err_mesg);
233  }
234 }
235 
236 namespace ocl {
237 
238 std::string CLErrorToString(cl_int error);
239 std::string CLErrorToString(cl_int* error);
240 void PrintOCLDebugInfo();
241 
242 }
243 
244 }
245 
246 #endif // JTYPETRAITS_H