NSVD Reader  0.0.1
derived_from_helper.hpp
Go to the documentation of this file.
1 
5 /*
6  * These codes are licensed under CC0.
7  * http://creativecommons.org/publicdomain/zero/1.0/
8  */
9 
10 #ifndef __NODAMUSHI_SVD_NORMALIZED_DERIVED_FROM_HELPER_HPP__
11 #define __NODAMUSHI_SVD_NORMALIZED_DERIVED_FROM_HELPER_HPP__
12 
13 # include <type_traits>
14 # include <string>
15 # if __cplusplus >= 201703
16 # include <string_view>
17 # endif
18 
20 
21 
22 namespace nodamushi{
23 namespace svd{
24 namespace normalized{
25 
26 //-------------------------------------------------------------------------------
27 
28 // name( svd.name.get() )
30 #define __NORMALIZED_DERIVED_FROM(name)\
31  ___NORMALIZED_DERIVED_FROM(n,name)
32 
33 
34 // name( svd.name )
35 #define __NORMALIZED_DERIVED_FROM_MEMBER(name)\
36  ___NORMALIZED_DERIVED_FROM_MEMBER(name,n)
37 
38 #define __NORMALIZED_DERIVED_FROM_HELPER(name)\
39  ___NORMALIZED_DERIVED_FROM_HELPER(name,n)
40 
41 
42 //-------------------------------------------------------------------------------
43 // Implements
44 //-------------------------------------------------------------------------------
45 
46 template<typename TO>
48 {
49  template<typename VALUE>
50  static TO cast_to(const VALUE* ptr)
51  {
52  if(ptr)return static_cast<TO>(ptr->get());
53  return TO{};
54  }
55 
56  template<typename VALUE,typename D>
57  static TO cast_to(const VALUE* ptr,D d)
58  {
59  if(ptr)return static_cast<TO>(ptr->get());
60  return static_cast<TO>(d);
61  }
62 };
63 
64 template<typename TO>
66 {
67  template<typename VALUE>
68  static nullable<TO> cast_to(const VALUE* ptr)
69  {
70  if(ptr)return {static_cast<TO>(ptr->get())};
71  else return {};
72  }
73  template<typename VALUE,typename D>
74  static nullable<TO> cast_to(const VALUE* ptr,D d)
75  {
76  if(ptr)return {static_cast<TO>(ptr->get())};
77  else return {static_cast<TO>(d)};
78  }
79 };
80 
81 
82 template<typename SVD,typename VALUE,VALUE SVD::* MEMBER>
84 {
85  using type =typename std::remove_const<typename VALUE::type>::type;
86 
87  const VALUE* ptr;
88 
89  template<typename O>
90  derived_from_helper(const O& o):
91  ptr(nullptr)
92  {
93  const auto& v = o.svd.*MEMBER;
94  if(v){
95  ptr = &v;
96  }else if(o.derivedFrom){
97  const O *df = o.derivedFrom;
98  while(df){
99  const auto& s= df->svd;
100  const auto& dv = s.*MEMBER;
101  if(dv){
102  ptr = &dv;
103  return;
104  }
105  df = df->derivedFrom;
106  }
107  }
108  }
109  operator bool()const noexcept{return ptr!=nullptr;}
110  auto operator*()const noexcept
111  ->decltype(ptr->get())
112  {
113  return ptr->get();
114  }
115 
116 };
117 
118 template<typename T,typename SVD,typename VALUE,VALUE SVD::* MEMBER>
121 }
122 
123 
124 template<typename T>struct unwrap_decltype
125 {
126  using unref = typename std::remove_reference<T>::type;
127  using type =typename std::remove_const<unref>::type;
128 };
129 
130 #define ___NORMALIZED_DERIVED_FROM(o,name) \
131  name(cast_df_helper<___NORMALIZED_DERIVED_FROM_FIELD_TYPE(name)>( \
132  ___NORMALIZED_DERIVED_FROM_TYPE(name,o){o})) \
133 
134 #define ___NORMALIZED_DERIVED_FROM_FIELD_TYPE(name) \
135  typename unwrap_decltype<decltype(this->name)>::type
136 
137 
138 #define ___NORMALIZED_DERIVED_FROM_TYPE(name,o) \
139  derived_from_helper< \
140  typename unwrap_decltype<decltype(o.svd)>::type,\
141  typename unwrap_decltype<decltype(o.svd.name)>::type,\
142  & unwrap_decltype<decltype(o.svd)>::type::name>
143 
144 #define ___NORMALIZED_DERIVED_FROM_MEMBER(name,o) \
145  name(derived_from_helper< \
146  typename unwrap_decltype<decltype(o.svd)>::type,\
147  typename unwrap_decltype<decltype(o.svd.name)>::type,\
148  & unwrap_decltype<decltype(o.svd)>::type::name>\
149  {o})
150 #define ___NORMALIZED_DERIVED_FROM_HELPER(name,o) \
151  derived_from_helper< \
152  typename unwrap_decltype<decltype(o.svd)>::type,\
153  typename unwrap_decltype<decltype(o.svd.name)>::type,\
154  & unwrap_decltype<decltype(o.svd)>::type::name>\
155  name{o}
156 
157 }}}// end namespace nodamushi::svd::normalized
158 
159 #endif // __NODAMUSHI_SVD_NORMALIZED_DERIVED_FROM_HELPER_HPP__
optional like container
typename std::remove_const< unref >::type type
typename std::remove_reference< T >::type unref
a data container like optional type.
Definition: nullable.hpp:21
auto cast_df_helper(derived_from_helper< SVD, VALUE, MEMBER > &&h)
typename std::remove_const< typename VALUE::type >::type type
auto operator *() const noexcept -> decltype(ptr->get())