1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 /**
19  * Variadic function wrapper around std::bitset. The general intent is that if
20  * you had:
21  *  enum states {a, b, c, d};
22  *
23  * You can create bitset to represent a set of states:
24  *
25  *  cb::bitset<4, states> permittedStates(a, c);
26  *  std::cout << permittedStates << "\n"; // 0101
27  *
28  * Or if you had:
29  *   enum states {a = 1, b, c, d};
30  *   struct states_mapper {
31  *      size_t map(states in) {
32  *          return in - 1;
33  *      }
34  *   }
35  *   cb::bitset<4, states, states_mapper> permittedStates(a, d);
36  *   std::cout << permittedStates << "\n"; // 1001
37  */
38 
39 #pragma once
40 
41 #include <bitset>
42 
43 namespace cb {
44 template <class Type>
45 struct default_bitset_mapper {
mapcb::default_bitset_mapper46     constexpr size_t map(Type t) const {
47         return size_t(t);
48     }
49 };
50 
51 template <std::size_t N, class Type, class Map = default_bitset_mapper<Type>>
52 class bitset {
53 public:
54     /// Default construct an empty bitset
bitset()55     bitset() {
56     }
57 
58     /// Construct bitset setting the specified values
59     template <class... Targs>
bitset(Type t, Targs... Fargs)60     bitset(Type t, Targs... Fargs) {
61         init(t, Fargs...);
62     }
63 
64     /// map and set the input t
set(Type t)65     void set(Type t) {
66         bits.set(Map().map(t));
67     }
68 
69     /// map and reset the input t
reset(Type t)70     void reset(Type t) {
71         bits.reset(Map().map(t));
72     }
73 
74     /// map and test the input t
test(Type t) const75     bool test(Type t) const {
76         return bits.test(Map().map(t));
77     }
78 
79 private:
80     template <class... Targs>
init(Type t, Targs... Fargs)81     void init(Type t, Targs... Fargs) {
82         init(t);
83         init(Fargs...);
84     }
85 
init(Type t)86     void init(Type t) {
87         this->set(t);
88     }
89 
90     std::bitset<N> bits;
91 };
92 
93 } // end namespace cb
94