evoq_bit_flags (evoq v1.14.1)
View SourceBit flag manipulation for aggregate state management.
This module provides functions for working with bitwise flags, which are particularly useful in event-sourced systems where aggregate state can be represented as a set of flags (finite state machine).
Why Use Bit Flags?
- Memory Efficiency: Store multiple boolean states in a single integer
- Performance: Bitwise operations are extremely fast
- Atomic Operations: Update multiple flags in a single operation
- Event Sourcing: Efficiently represent aggregate state in event streams
- Database Queries: Use bitwise operators in SQL/NoSQL queries
Flag Values
Flags must be powers of 2 to occupy unique bit positions:
-define(NONE, 0). % 2#00000000
-define(CREATED, 1). % 2#00000001
-define(VALIDATED, 2). % 2#00000010
-define(PROCESSING, 4). % 2#00000100
-define(COMPLETED, 8). % 2#00001000
-define(CANCELLED, 16). % 2#00010000
-define(ARCHIVED, 32). % 2#00100000Example Usage
%% Start with no flags
State0 = 0,
%% Set CREATED flag
State1 = evoq_bit_flags:set(State0, 1), % State1 = 1
%% Set VALIDATED flag
State2 = evoq_bit_flags:set(State1, 2), % State2 = 3
%% Check if CREATED is set
true = evoq_bit_flags:has(State2, 1),
%% Check if CANCELLED is set
false = evoq_bit_flags:has(State2, 16).Inspired by C# Flags enum attribute.
Summary
Functions
Decomposes a number into its power-of-2 components.
Returns true if the flag is set in the target state.
Returns true if ALL flags are set in the target state.
Returns true if ANY flag is set in the target state.
Returns true if the flag is NOT set in the target state.
Returns the description of the highest set flag.
Returns the description of the lowest set flag.
Sets a flag in the target state using bitwise OR.
Sets multiple flags in the target state.
Returns a list of flag descriptions that are set in the target state.
Returns a comma-separated string of flag descriptions.
Returns a string of flag descriptions with custom separator.
Unsets a flag in the target state using bitwise AND with NOT.
Unsets multiple flags in the target state.
Types
-type flag() :: pos_integer().
-type flag_map() :: #{non_neg_integer() => binary() | string()}.
-type flags() :: non_neg_integer().
Functions
Decomposes a number into its power-of-2 components.
Example:
[4, 32, 64] = evoq_bit_flags:decompose(100).
[1, 2, 4, 8] = evoq_bit_flags:decompose(15).
Returns true if the flag is set in the target state.
Example:
true = evoq_bit_flags:has(100, 64).
false = evoq_bit_flags:has(100, 8).
Returns true if ALL flags are set in the target state.
Example:
true = evoq_bit_flags:has_all(100, [4, 32, 64]).
false = evoq_bit_flags:has_all(100, [4, 8]).
Returns true if ANY flag is set in the target state.
Example:
true = evoq_bit_flags:has_any(100, [8, 64]).
false = evoq_bit_flags:has_any(100, [1, 2, 8]).
Returns true if the flag is NOT set in the target state.
Example:
false = evoq_bit_flags:has_not(100, 64).
true = evoq_bit_flags:has_not(100, 8).
Returns the description of the highest set flag.
Example:
<<"Ready">> = evoq_bit_flags:highest(100, #{4 => <<"Completed">>, 32 => <<"Archived">>, 64 => <<"Ready">>}).
Returns the description of the lowest set flag.
Example:
<<"Completed">> = evoq_bit_flags:lowest(100, #{4 => <<"Completed">>, 32 => <<"Archived">>, 64 => <<"Ready">>}).
Sets a flag in the target state using bitwise OR.
Example:
100 = evoq_bit_flags:set(36, 64).
%% 36 = 2#00100100, 64 = 2#01000000
%% Result: 2#01100100 = 100
Sets multiple flags in the target state.
Example:
228 = evoq_bit_flags:set_all(36, [64, 128]).
Returns a list of flag descriptions that are set in the target state.
Example:
FlagMap = #{0 => <<"None">>, 4 => <<"Completed">>, 32 => <<"Archived">>, 64 => <<"Ready">>},
[<<"Completed">>, <<"Archived">>, <<"Ready">>] = evoq_bit_flags:to_list(100, FlagMap).
Returns a comma-separated string of flag descriptions.
Example:
FlagMap = #{4 => <<"Completed">>, 32 => <<"Archived">>, 64 => <<"Ready">>},
<<"Completed, Archived, Ready">> = evoq_bit_flags:to_string(100, FlagMap).
Returns a string of flag descriptions with custom separator.
Example:
<<"Completed | Archived | Ready">> = evoq_bit_flags:to_string(100, FlagMap, <<" | ">>).
Unsets a flag in the target state using bitwise AND with NOT.
Example:
36 = evoq_bit_flags:unset(100, 64).
%% 100 = 2#01100100, 64 = 2#01000000
%% Result: 2#00100100 = 36
Unsets multiple flags in the target state.
Example:
36 = evoq_bit_flags:unset_all(228, [64, 128]).