mf
Media Framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
masked_elem.h
Go to the documentation of this file.
1 #ifndef MF_MASKED_ELEM_H_
2 #define MF_MASKED_ELEM_H_
3 
4 #include "elem.h"
5 #include <cstddef>
6 #include <type_traits>
7 
8 namespace mf {
9 
11 
14 template<typename Elem, typename = void>
15 struct masked_elem {
16  static_assert(! std::is_const<Elem>::value, "masked_elem cannot have const Elem");
17  static_assert(! elem_traits<Elem>::is_nullable, "masked_elem elem cannot be nullable in this specialization");
18 
19  Elem elem;
20  bool mask;
21 
22  static masked_elem null() { return masked_elem(); }
23  bool is_null() const { return ! mask; }
24  explicit operator bool () const { return ! is_null(); }
25 
26  masked_elem() : elem(), mask(false) { }
27  masked_elem(const Elem& el) : elem(el), mask(true) { }
28  masked_elem(const masked_elem&) = default;
29 
30  masked_elem& operator=(const masked_elem&) = default;
31  masked_elem& operator=(const Elem& el) { elem = el; mask = true; return *this; }
32 
33  friend bool operator==(const masked_elem& a, const masked_elem& b) {
34  if(a.mask && b.mask) return true;
35  else if(a.mask != b.mask) return false;
36  else return (a.elem == b.elem);
37  }
38  friend bool operator!=(const masked_elem& a, const masked_elem& b) {
39  return !(a == b);
40  }
41 
42  operator const Elem& () const { MF_EXPECTS(mask); return elem; }
43  operator Elem& () { MF_EXPECTS(mask); return elem; }
44 };
45 
46 
48 
49 template<typename Elem>
50 class masked_elem<Elem, std::enable_if_t<elem_traits<Elem>::is_nullable>> {
51  static_assert(! std::is_const<Elem>::value, "masked_elem cannot have const Elem");
52  static_assert(elem_traits<Elem>::is_nullable, "masked_elem elem must be nullable in this specialization");
53 
54  Elem elem;
55 
56  static masked_elem null() { return masked_elem(); }
57  bool is_null() const { return elem.is_null(); }
58  explicit operator bool () const { return ! is_null(); }
59 
60  masked_elem() : elem(Elem::null()) { }
61  masked_elem(const Elem& el) : elem(el) { }
62  masked_elem(const masked_elem&) = default;
63 
64  masked_elem& operator=(const masked_elem&) = default;
65  masked_elem& operator=(const Elem& el) { elem = el; return *this; }
66 
67  friend bool operator==(const masked_elem& a, const masked_elem& b) {
68  return (a.elem == b.elem);
69  }
70  friend bool operator!=(const masked_elem& a, const masked_elem& b) {
71  return !(a == b);
72  }
73 
74  operator const Elem& () const { return elem; }
75  operator Elem& () { return elem; }
76 };
77 
78 
79 // TODO const support
80 
82 
83 template<typename Elem>
84 struct elem_traits<masked_elem<Elem>> :
85  elem_traits_base<masked_elem<Elem>, masked_elem<Elem>, 1, true> { };
86 
87 
88 namespace detail {
89  template<typename Elem>
90  struct unmasked_type {
91  using type = Elem;
92  };
93 
94  template<typename Elem>
95  struct unmasked_type<masked_elem<Elem>> {
96  using type = Elem;
97  };
98 
99  template<typename Elem>
100  struct masked_type {
101  using type = masked_elem<Elem>;
102  };
103 
104  template<typename Elem>
105  struct masked_type<masked_elem<Elem>> {
106  using type = masked_elem<Elem>;
107  };
108 }
109 
110 
112 template<typename Elem> using masked_type = typename detail::masked_type<Elem>::type;
113 
114 
116 template<typename Elem> using unmasked_type = typename detail::unmasked_type<Elem>::type;
117 
118 
119 }
120 
121 #endif
masked_elem & operator=(const Elem &el)
Definition: masked_elem.h:31
masked_elem & operator=(const masked_elem &)=default
masked_elem()
Definition: masked_elem.h:26
Elem elem
Non-nullable element.
Definition: masked_elem.h:16
static masked_elem null()
Definition: masked_elem.h:22
bool is_null() const
Definition: masked_elem.h:23
Nullable wrapper for elem type which adds mask.
Definition: masked_elem.h:15
friend bool operator!=(const masked_elem &a, const masked_elem &b)
Definition: masked_elem.h:38
friend bool operator==(const masked_elem &a, const masked_elem &b)
Definition: masked_elem.h:67
Elem traits base class with the required members.
Definition: elem.h:14
typename detail::unmasked_type< Elem >::type unmasked_type
Remove mask to type Elem, if is is a masked_type.
Definition: masked_elem.h:116
#define MF_EXPECTS(condition)
Definition: common.h:27
Default elem traits, using Elem as standard layout scalar type.
Definition: elem.h:30
friend bool operator==(const masked_elem &a, const masked_elem &b)
Definition: masked_elem.h:33
typename detail::masked_type< Elem >::type masked_type
Add mask to type Elem, if not already a masked_type.
Definition: masked_elem.h:112
friend bool operator!=(const masked_elem &a, const masked_elem &b)
Definition: masked_elem.h:70
bool mask
Mask, false if masked_elem is null.
Definition: masked_elem.h:20
masked_elem(const Elem &el)
Definition: masked_elem.h:27