mrs_lib
Various reusable classes, functions and utilities for use in MRS projects
vector_converter.hpp
Go to the documentation of this file.
1 
5 #ifndef VECTOR_CONVERTER_HPP
6 #define VECTOR_CONVERTER_HPP
7 
8 #include <experimental/type_traits>
9 
10 namespace mrs_lib
11 {
12  namespace impl
13  {
14  using unw_t = std::tuple<double, double, double>;
15 
16  /* SFINAE magic - only for black wizards! //{ */
17 
18  #define GENERATE_HAS_MEMBER_FUNC(func, rettype) \
19  template<class T> using _has_##func##fun_chk = \
20  decltype(std::declval<T &>().func()); \
21  template<class T> constexpr bool has_##func##fun_v = \
22  std::experimental::is_detected_convertible_v<rettype, _has_##func##fun_chk, T>;
23 
24  #define GENERATE_HAS_MEMBER(memb, type) \
25  template<class T> using _has_##memb##mem_chk = \
26  decltype(std::declval<T &>().memb); \
27  template<class T> constexpr bool has_##memb##mem_v = \
28  std::experimental::is_detected_convertible_v<type, _has_##memb##mem_chk, T>;
29 
30  GENERATE_HAS_MEMBER_FUNC(x, double)
31  GENERATE_HAS_MEMBER(x, double)
32 
33  template<class T> using _has_squarebracket_operator_chk = decltype(std::declval<T &>()[0]);
34  template<class T> constexpr bool has_squarebracket_operator_v = std::experimental::is_detected_convertible_v<double, _has_squarebracket_operator_chk, T>;
35 
36  template<class T> constexpr bool has_xyz_constructor_v = std::experimental::is_constructible_v<T, double, double, double>;
37 
38  //}
39 
40  // convertFrom specialization for Eigen types
41  template <typename in_t>
42  std::enable_if_t<has_xfun_v<in_t>, unw_t> convertFrom(const in_t& in)
43  {
44  return {in.x(), in.y(), in.z()};
45  }
46 
47  // convertFrom specialization for plain member types
48  template <typename in_t>
49  std::enable_if_t<has_xmem_v<in_t>, unw_t> convertFrom(const in_t& in)
50  {
51  return {in.x, in.y, in.z};
52  }
53 
54  // convertFrom specialization for OpenCV vectors
55  template <typename in_t>
56  std::enable_if_t<has_squarebracket_operator_v<in_t> && !has_xfun_v<in_t>, unw_t> convertFrom(const in_t& in)
57  {
58  return {in[0], in[1], in[2]};
59  }
60 
61  // convertTo specialization for types with a constructor that takes three doubles
62  template <typename ret_t>
63  std::enable_if_t<has_xyz_constructor_v<ret_t>, void> convertTo(ret_t& out, const double x, const double y, const double z)
64  {
65  out = {x, y, z};
66  }
67 
68  // convertTo specialization for other types
69  template <typename ret_t>
70  std::enable_if_t<!has_xyz_constructor_v<ret_t> && has_xmem_v<ret_t>, void> convertTo(ret_t& out, const double x, const double y, const double z)
71  {
72  out.x = x;
73  out.y = y;
74  out.z = z;
75  }
76 
77  template <typename ret_t>
78  ret_t convertTo(const double x, const double y, const double z)
79  {
80  ret_t ret;
81  convertTo(ret, x, y, z);
82  return ret;
83  }
84 
85  } // namespace impl
86 
87 } // namespace mrs_lib
88 
89 #endif // VECTOR_CONVERTER_HPP
mrs_lib
All mrs_lib functions, classes, variables and definitions are contained in this namespace.
Definition: attitude_converter.h:29