NSVD Reader  0.0.1
reg_or_cluster.hpp
Go to the documentation of this file.
1 
9 #ifndef __NODAMUSHI_REGISTERORCLUSTER_HPP__
10 #define __NODAMUSHI_REGISTERORCLUSTER_HPP__
11 
12 # include <memory>
13 # include <functional>
14 # include <exception>
15 
16 namespace nodamushi{
17 namespace svd{
18 
22 template<typename REG,typename CLUSTER>struct reg_or_cluster
23 {
24  using reg_t = REG;
25  using clu_t = CLUSTER;
26  using deleter = std::function<void(void*)>;
27 
28  reg_or_cluster(const reg_or_cluster&)=delete;
29  reg_or_cluster& operator=(const reg_or_cluster&) = delete;
30  // move only
31  reg_or_cluster(reg_or_cluster&&)=default;
33 
35  reg(true),p(r,[](void *v){delete static_cast<reg_t*>(v);}){}
37  reg(false),p(c,[](void *v){delete static_cast<clu_t*>(v);}){}
38 
42  bool is_register()const noexcept{return reg;}
46  bool is_cluster()const noexcept{return !reg;}
52  if(!reg){
53  throw std::runtime_error("bad cast.not a register");
54  }
55  void* d = p.get();
56  if(!d){
57  throw std::runtime_error("register is empty");
58  }
59  reg_t* r = static_cast<reg_t*>(d);
60  return *r;
61  }
67  if(reg){
68  throw std::runtime_error("bad cast.not a cluster");
69  }
70  void* d = p.get();
71  if(!d){
72  throw std::runtime_error("cluster is empty");
73  }
74  clu_t* r = static_cast<clu_t*>(d);
75  return *r;
76  }
81  const reg_t& get_register()const{
82  if(!reg){
83  throw std::runtime_error("bad cast.not a register");
84  }
85  void* d = p.get();
86  if(!d){
87  throw std::runtime_error("register is empty");
88  }
89  reg_t* r = static_cast<reg_t*>(d);
90  return *r;
91  }
96  const clu_t& get_cluster()const{
97  if(reg){
98  throw std::runtime_error("bad cast.not a cluster");
99  }
100  void* d = p.get();
101  if(!d){
102  throw std::runtime_error("cluster is empty");
103  }
104  clu_t* r = static_cast<clu_t*>(d);
105  return *r;
106  }
107 
108  const void* get(){return p.get();}
109  private:
110  bool reg;
111  std::unique_ptr<void, deleter> p;
112 };
113 
114 
115 template<bool IS_REGISTER>struct register_cluster_selector;
116 
117 template<>struct register_cluster_selector<true>
118 {
119  static constexpr bool is_register = true;
120  template<typename R,typename C>
121  static constexpr const R& select(const R& r,const C& c){return r;}
122  template<typename R,typename C>
123  static constexpr R& select(R& r,C& c){return r;}
124  template<typename R,typename C>
125  static const R* get(const reg_or_cluster<R,C>& rc){
126  if(rc.is_register()){return &rc.get_register();}
127  return nullptr;
128  }
129  template<typename R,typename C>
130  static R* get(reg_or_cluster<R,C>& rc){
131  if(rc.is_register()){return &rc.get_register();}
132  return nullptr;
133  }
134 
135 };
136 
137 template<>struct register_cluster_selector<false>
138 {
139  static constexpr bool is_register = false;
140  template<typename R,typename C>
141  static constexpr const C& select(const R& r,const C& c){return c;}
142  template<typename R,typename C>
143  static constexpr C& select(R& r,C& c){return c;}
144 
145  template<typename R,typename C>
146  static const C* get(const reg_or_cluster<R,C>& rc){
147  if(rc.is_cluster()){return &rc.get_cluster();}
148  return nullptr;
149  }
150  template<typename R,typename C>
151  static C* get(reg_or_cluster<R,C>& rc){
152  if(rc.is_cluster()){return &rc.get_cluster();}
153  return nullptr;
154  }
155 
156 };
157 
158 
159 }} // end namespace nodamushi
160 
161 #endif // __NODAMUSHI_REGISTERORCLUSTER_HPP__
static C * get(reg_or_cluster< R, C > &rc)
const clu_t & get_cluster() const
unique_ptr<Register> or unique_ptr<Cluster>
reg_or_cluster & operator=(const reg_or_cluster &)=delete
static R * get(reg_or_cluster< R, C > &rc)
static constexpr const R & select(const R &r, const C &c)
std::function< void(void *)> deleter
static const R * get(const reg_or_cluster< R, C > &rc)
const reg_t & get_register() const
static constexpr const C & select(const R &r, const C &c)
reg_or_cluster(const reg_or_cluster &)=delete
bool is_register() const noexcept
static const C * get(const reg_or_cluster< R, C > &rc)
bool is_cluster() const noexcept