libqi-api  2.8.7.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flags.hpp
Go to the documentation of this file.
1 /*
2 ** Copyright (C) 2017 SoftBank Robotics
3 ** See COPYING for the license
4 */
5 
6 #ifndef QI_FLAGS_HPP
7 #define QI_FLAGS_HPP
8 
9 #include <ka/typetraits.hpp>
10 #include <ka/macroregular.hpp>
11 #include <boost/range/adaptor/transformed.hpp>
12 #include <boost/range/numeric.hpp>
13 #include <algorithm>
14 
15 namespace qi
16 {
21  template <typename E, typename = ka::EnableIf<std::is_enum<E>::value>>
22  auto underlying(const E& e) -> ka::UnderlyingType<E>
23  {
24  return static_cast<ka::UnderlyingType<E>>(e);
25  }
26 
59  template <typename Type>
60  class Flags
61  {
62  public:
63  using type = Type;
64  using underlying_type = ka::Decay<decltype(underlying(std::declval<Type>()))>;
65 
66  private:
67  explicit Flags(underlying_type value)
68  : _value(value)
69  {}
70 
71  public:
72  // Regular:
74  : _value{}
75  {}
76 
77  KA_GENERATE_FRIEND_REGULAR_OPS_1(Flags, _value)
78 
79  // HasUnderlying:
80  friend const underlying_type& underlying(const Flags& f)
81  {
82  return f._value;
83  }
84 
85  // Custom:
86  explicit Flags(std::initializer_list<Type> values)
87  : _value(boost::accumulate(values | boost::adaptors::transformed([](const Type& t) { return underlying(t); }),
89  std::bit_or<underlying_type>()))
90  {}
91 
92  explicit Flags(const Type& t)
93  : _value(underlying(t))
94  {}
95 
96  bool test(const Type& t) const
97  {
98  return (_value & underlying(t)) != underlying_type{};
99  }
100 
101  Flags& set(const Type& t)
102  {
103  _value |= underlying(t);
104  return *this;
105  }
106 
107  Flags& reset(const Type& t)
108  {
109  _value &= ~underlying(t);
110  return *this;
111  }
112 
113  friend Flags operator&(const Flags& a, const Flags& b)
114  {
115  return Flags{a._value & b._value};
116  }
117 
118  friend Flags operator|(const Flags& a, const Flags& b)
119  {
120  return Flags{a._value | b._value};
121  }
122 
123  friend Flags operator^(const Flags& a, const Flags& b)
124  {
125  return Flags{a._value ^ b._value};
126  }
127 
128  friend Flags operator~(const Flags& a)
129  {
130  return Flags{~a._value};
131  }
132 
133  friend Flags& operator|=(Flags& a, const Flags& b)
134  {
135  a._value |= b._value;
136  return a;
137  }
138 
139  friend Flags& operator&=(Flags& a, const Flags& b)
140  {
141  a._value &= b._value;
142  return a;
143  }
144 
145  friend Flags& operator^=(Flags& a, const Flags& b)
146  {
147  a._value ^= b._value;
148  return a;
149  }
150 
151  private:
152  underlying_type _value;
153  };
154 }
155 
156 #endif // QI_FLAGS_HPP
Flags & set(const Type &t)
Definition: flags.hpp:101
friend const underlying_type & underlying(const Flags &f)
Definition: flags.hpp:80
friend Flags operator~(const Flags &a)
Definition: flags.hpp:128
friend Flags & operator^=(Flags &a, const Flags &b)
Definition: flags.hpp:145
friend Flags operator^(const Flags &a, const Flags &b)
Definition: flags.hpp:123
friend Flags operator&(const Flags &a, const Flags &b)
Definition: flags.hpp:113
Flags(std::initializer_list< Type > values)
Definition: flags.hpp:86
Flags & reset(const Type &t)
Definition: flags.hpp:107
ka::Decay< decltype(underlying(std::declval< Option >()))> underlying_type
Definition: flags.hpp:64
friend Flags & operator|=(Flags &a, const Flags &b)
Definition: flags.hpp:133
friend Flags & operator&=(Flags &a, const Flags &b)
Definition: flags.hpp:139
Flags(const Type &t)
Definition: flags.hpp:92
bool test(const Type &t) const
Definition: flags.hpp:96
auto underlying(const E &e) -> ka::UnderlyingType< E >
Definition: flags.hpp:22
Flags()
Definition: flags.hpp:73
friend Flags operator|(const Flags &a, const Flags &b)
Definition: flags.hpp:118