farm-ng-core
enum_flags_without_ostream.h
Go to the documentation of this file.
1 // Copyright 2022, farm-ng inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // FARM_ENUM is a fork of MY_ENUM.
16 //
17 // https://github.com/facebookincubator/MY_ENUM/
18 //
19 // Copyright (c) Facebook, Inc. and its affiliates.
20 //
21 // This source code is licensed under the MIT license found in the
22 // LICENSE file in the root directory of this source tree.
23 
24 #pragma once
25 
27 
28 /* FARM_ENUMFLAGS_WITHOUT_OSTREAM_DEF(NAME, UINT_TYPE, ARGS)
29 
30  Enum flags type definition. Can be in global, and namespace scope only. See
31  FARM_ENUMFLAGS_WITHOUT_OSTREAM below for details. */
32 #define FARM_ENUMFLAGS_WITHOUT_OSTREAM_DEF(NAME, UINT_TYPE, ...) \
33  FARM_ENUMFLAGS_DEF_IMPL(NAME, UINT_TYPE, __VA_ARGS__)
34 
35 /* FARM_ENUMFLAGS_ALIAS(NAME)
36 
37  Enum type alias. Can be in any scope. See FARM_ENUMFLAGS_WITHOUT_OSTREAM for
38  details. */
39 #define FARM_ENUMFLAGS_ALIAS(NAME) using NAME = enum_wrapper_::NAME##Impl
40 
41 /* FARM_ENUMFLAGS_WITHOUT_OSTREAM(NAME, UINT_TYPE, ARGS)
42 
43  Enum flag type. Can be in global, and namespace scope only.
44 
45  NAME: Name of the enum flag class.
46  UINT_TYPE: unsigned integral type.
47  ARGS: Tuple of enums, such as (foo, bar, da).
48 
49  For example ``FARM_ENUMFLAGS_WITHOUT_OSTREAM(MyFlags, uint32_t, (foo, bar,
50  daz));`` defines an enum class
51 
52  enum class MyFlags : uint32_t {
53  none = 0,
54  foo = 1,
55  bar = 2,
56  daz = 4
57  };
58 
59  with the following free functions:
60 
61  // Bitwise or
62  MyFlags operator|(MyFlags left, MyFlags right);
63 
64  // Bitwise and
65  MyFlags operator&(MyFlags left, MyFlags right);
66 
67  // Sets corresponding bit to 1, if string is single flag (i.e. "foo", "bar"
68  // or "daz"). Returns false otherwise.
69  bool trySetFlagFromString(MyFlags& value, const std::string& str);
70 
71  // Return true if ``value`` contains all flags in ``mask``.
72  bool hasMask(MyFlags value, MyFlags mask);
73 
74  // Enables bits in mask.
75  void setMask(MyFlags& value, MyFlags mask);
76 
77  // Clear bits in mask.
78  void clearMask(MyFlags& value, MyFlags mask);
79 
80  // Toggle bits.
81  void toggleMask(MyFlags& value, MyFlags mask);
82 
83  // Returns true if value is a single flag (i.e. Foo::foo, Foo::bar or
84  // Foo::daz)
85  bool isSingleFlag(MyFlags value);
86 
87  // Returns string representation of enabled flags
88  // (e.g. {"foo", "bar"} for `MyFlags::foo | MyFlags::bar')
89  std::vector<std::string> toStrings(MyFlags value);
90 
91  // Return pretty string representation
92  // (e.g. "{bar (=2), daz (=4)}" for `MyFlags::bar | MyFlags::daz').
93  std::string toPretty(MyFlags value);
94 
95  // Returns number of flags (i.e. 3).
96  constexpr size_t getCount(MyFlags) {
97  return 3u;
98  }
99 
100  // Returns array of names:
101  std::array<string_view, 3> getNames(MyFlags) {
102  return {"foo", "bar", "daz"};
103  }
104 
105  // Return string of names:
106  constexpr string_view getStringOfNames(MyFlags) {
107  return "{foo, bar, daz}";
108  }
109 
110  // Returns array of values:
111  constexpr std::array<uint32_t, 3u> getValues(MyFlags) {
112  return {1, 2, 4};
113  }
114 
115  string_view getTypeName(MyFlags) {
116  return "MyFlags";
117  }
118 
119  // Note: When adding new flags to an existing enum, we want to add such flag
120  // at the end.
121 
122  FARM_ENUMFLAGS_WITHOUT_OSTREAM(MyFlags, uint32_t, (foo, bar));
123 
124  generates
125 
126  enum class MyFlags : uint32_t {
127  none = 0,
128  foo = 1,
129  bar = 2
130  };
131 
132 
133  Now adding "daz" to the end, we get
134 
135 
136  FARM_ENUMFLAGS_WITHOUT_OSTREAM(MyFlags, uint32_t, (foo, bar, daz));
137 
138  which generates
139 
140  enum class MyFlags : uint32_t {
141  none = 0,
142  foo = 1,
143  bar = 2,
144  daz = 4
145  };
146 
147  And hence the order of exiting flags (foo, bar) is respected and their
148  values do not change.
149 */
150 #define FARM_ENUMFLAGS_WITHOUT_OSTREAM(NAME, UINT_TYPE, ...) \
151  FARM_ENUMFLAGS_WITHOUT_OSTREAM_DEF(NAME, UINT_TYPE, __VA_ARGS__) \
152  FARM_ENUMFLAGS_ALIAS(NAME)
enum_flag_details.h