Matter SDK Coverage Report
Current view: top level - lib/support - BitFlags.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 100.0 % 38 38
Test Date: 2025-01-17 19:00:11 Functions: 84.9 % 251 213

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    Copyright (c) 2013-2017 Nest Labs, Inc.
       5              :  *
       6              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       7              :  *    you may not use this file except in compliance with the License.
       8              :  *    You may obtain a copy of the License at
       9              :  *
      10              :  *        http://www.apache.org/licenses/LICENSE-2.0
      11              :  *
      12              :  *    Unless required by applicable law or agreed to in writing, software
      13              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      14              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15              :  *    See the License for the specific language governing permissions and
      16              :  *    limitations under the License.
      17              :  */
      18              : 
      19              : /**
      20              :  *    @file
      21              :  *      This file defines functions for manipulating Boolean flags in
      22              :  *      a bitfield.
      23              :  *
      24              :  */
      25              : 
      26              : #pragma once
      27              : 
      28              : #include <stdint.h>
      29              : 
      30              : #include <type_traits>
      31              : #include <utility>
      32              : 
      33              : namespace chip {
      34              : 
      35              : /**
      36              :  * Stores bit flags in a type safe manner.
      37              :  *
      38              :  * @tparam FlagsEnum is an `enum` or (preferably) `enum class` type.
      39              :  * @tparam StorageType is the underlying storage type (like uint16_t, uint32_t etc.)
      40              :  *         and defaults to the underlying storage type of `FlagsEnum`.
      41              :  */
      42              : template <typename FlagsEnum, typename StorageType = typename std::underlying_type_t<FlagsEnum>>
      43              : class BitFlags
      44              : {
      45              : public:
      46              :     static_assert(sizeof(StorageType) >= sizeof(FlagsEnum), "All flags should fit in the storage type");
      47              :     using IntegerType = StorageType;
      48              : 
      49       148260 :     constexpr BitFlags() : mValue(0) {}
      50              :     BitFlags(const BitFlags & other)       = default;
      51              :     BitFlags & operator=(const BitFlags &) = default;
      52              : 
      53         4697 :     explicit constexpr BitFlags(FlagsEnum value) : mValue(static_cast<IntegerType>(value)) {}
      54         2884 :     explicit constexpr BitFlags(IntegerType value) : mValue(value) {}
      55              : 
      56              :     template <typename... Args>
      57        18919 :     constexpr BitFlags(FlagsEnum flag, Args &&... args) : mValue(Or(flag, std::forward<Args>(args)...))
      58        18919 :     {}
      59              : 
      60              :     template <typename... Args>
      61              :     constexpr BitFlags(const BitFlags<FlagsEnum> & flags, Args &&... args) : mValue(Or(flags, std::forward<Args>(args)...))
      62              :     {}
      63              : 
      64              :     template <typename... Args>
      65           24 :     constexpr BitFlags(IntegerType value, Args &&... args) : mValue(value | Or(std::forward<Args>(args)...))
      66           24 :     {}
      67              : 
      68              :     /**
      69              :      * Set flag(s).
      70              :      *
      71              :      * @param other     Flag(s) to set. Any flags not set in @a other are unaffected.
      72              :      */
      73              :     BitFlags & Set(const BitFlags & other)
      74              :     {
      75              :         mValue |= other.mValue;
      76              :         return *this;
      77              :     }
      78              : 
      79              :     /**
      80              :      * Set flag(s).
      81              :      *
      82              :      * @param flag      Typed flag(s) to set. Any flags not in @a v are unaffected.
      83              :      */
      84      6730013 :     constexpr BitFlags & Set(FlagsEnum flag)
      85              :     {
      86      6730013 :         mValue |= static_cast<IntegerType>(flag);
      87      6730013 :         return *this;
      88              :     }
      89              : 
      90              :     /**
      91              :      * Set or clear flag(s).
      92              :      *
      93              :      * @param flag      Typed flag(s) to set or clear. Any flags not in @a flag are unaffected.
      94              :      * @param isSet     If true, set the flag; if false, clear it.
      95              :      */
      96       256287 :     constexpr BitFlags & Set(FlagsEnum flag, bool isSet) { return isSet ? Set(flag) : Clear(flag); }
      97              : 
      98              :     /**
      99              :      * Clear flag(s).
     100              :      *
     101              :      * @param other     Typed flag(s) to clear. Any flags not in @a other are unaffected.
     102              :      */
     103              :     BitFlags & Clear(const BitFlags & other)
     104              :     {
     105              :         mValue &= static_cast<IntegerType>(~static_cast<IntegerType>(other.mValue));
     106              :         return *this;
     107              :     }
     108              : 
     109              :     /**
     110              :      * Clear flag(s).
     111              :      *
     112              :      * @param flag  Typed flag(s) to clear. Any flags not in @a flag are unaffected.
     113              :      */
     114       179644 :     constexpr BitFlags & Clear(FlagsEnum flag)
     115              :     {
     116       179644 :         mValue &= static_cast<IntegerType>(~static_cast<IntegerType>(flag));
     117       179644 :         return *this;
     118              :     }
     119              : 
     120              :     /**
     121              :      * Clear all flags.
     122              :      */
     123        35182 :     BitFlags & ClearAll()
     124              :     {
     125        35182 :         mValue = 0;
     126        35182 :         return *this;
     127              :     }
     128              : 
     129              :     /**
     130              :      * Check whether flag(s) are set.
     131              :      *
     132              :      * @param flag      Flag(s) to test.
     133              :      * @returns         True if any flag in @a flag is set, otherwise false.
     134              :      */
     135     13931800 :     constexpr bool Has(FlagsEnum flag) const { return (mValue & static_cast<IntegerType>(flag)) != 0; }
     136              : 
     137              :     /**
     138              :      * Check that no flags outside the arguments are set.
     139              :      *
     140              :      * @param args      Flags to test. Arguments can be BitFlags<FlagsEnum>, BitFlags<FlagsEnum>, or FlagsEnum.
     141              :      * @returns         True if no flag is set other than those passed.
     142              :      *                  False if any flag is set other than those passed.
     143              :      *
     144              :      * @note            Flags passed need not be set; this test only requires that no *other* flags be set.
     145              :      */
     146              :     template <typename... Args>
     147         2937 :     bool HasOnly(Args &&... args) const
     148              :     {
     149         2937 :         return (mValue & Or(std::forward<Args>(args)...)) == mValue;
     150              :     }
     151              : 
     152              :     /**
     153              :      * Check that all given flags are set.
     154              :      *
     155              :      * @param args      Flags to test. Arguments can be BitFlags<FlagsEnum>, BitFlags<FlagsEnum>, or FlagsEnum.
     156              :      * @returns         True if all given flags are set.
     157              :      *                  False if any given flag is not set.
     158              :      */
     159              :     template <typename... Args>
     160        30126 :     bool HasAll(Args &&... args) const
     161              :     {
     162        30126 :         const IntegerType all = Or(std::forward<Args>(args)...);
     163        30126 :         return (mValue & all) == all;
     164              :     }
     165              : 
     166              :     /**
     167              :      * Check that at least one of the given flags is set.
     168              :      *
     169              :      * @param args      Flags to test. Arguments can be BitFlags<FlagsEnum>, BitFlags<FlagsEnum>, or FlagsEnum.
     170              :      * @returns         True if all given flags are set.
     171              :      *                  False if any given flag is not set.
     172              :      */
     173              :     template <typename... Args>
     174         2926 :     bool HasAny(Args &&... args) const
     175              :     {
     176         2926 :         return (mValue & Or(std::forward<Args>(args)...)) != 0;
     177              :     }
     178              : 
     179              :     /**
     180              :      * Check that at least one flag is set.
     181              :      *
     182              :      * @returns         True if any flag is set, false otherwise.
     183              :      */
     184      6603483 :     bool HasAny() const { return mValue != 0; }
     185              : 
     186              :     /**
     187              :      * Find the logical intersection of flags.
     188              :      *
     189              :      * @param lhs       Some flags.
     190              :      * @param rhs       Some flags.
     191              :      * @returns         Flags set in both @a lhs and @a rhs.
     192              :      *
     193              :      * @note: A multi-argument `BitFlags` constructor serves the function of `operator|`.
     194              :      */
     195            5 :     friend BitFlags<FlagsEnum> operator&(BitFlags<FlagsEnum> lhs, const BitFlags<FlagsEnum> & rhs)
     196              :     {
     197            5 :         return BitFlags<FlagsEnum>(lhs.mValue & rhs.mValue);
     198              :     }
     199              : 
     200              :     /**
     201              :      * Get the flags as the type FlagsEnum.
     202              :      *
     203              :      * @note            This allows easily storing flags as a base FlagsEnum in a POD type,
     204              :      *                  and enables equality comparisons.
     205              :      */
     206          103 :     operator FlagsEnum() const { return static_cast<FlagsEnum>(mValue); }
     207              : 
     208              :     /**
     209              :      * Set and/or clear all flags with a value of the underlying storage type.
     210              :      *
     211              :      * @param value     New storage value.
     212              :      */
     213        90831 :     BitFlags & SetRaw(IntegerType value)
     214              :     {
     215        90831 :         mValue = value;
     216        90831 :         return *this;
     217              :     }
     218              : 
     219              :     /**
     220              :      * Get the flags as the underlying integer type.
     221              :      *
     222              :      * @note            This is intended to be used only to store flags into a raw binary record.
     223              :      */
     224        99412 :     constexpr IntegerType Raw() const { return mValue; }
     225              : 
     226              :     /**
     227              :      * Get the address of the flags as a pointer to the underlying integer type.
     228              :      *
     229              :      * @note            This is intended to be used only to read flags from a raw binary record.
     230              :      */
     231           17 :     StorageType * RawStorage() { return &mValue; }
     232              : 
     233              : private:
     234              :     // Find the union of BitFlags and/or FlagsEnum values.
     235              :     template <typename... Args>
     236        55836 :     static constexpr IntegerType Or(FlagsEnum flag, Args &&... args)
     237              :     {
     238        55836 :         return static_cast<IntegerType>(flag) | Or(std::forward<Args>(args)...);
     239              :     }
     240              :     template <typename... Args>
     241              :     static constexpr IntegerType Or(const BitFlags<FlagsEnum> & flags, Args &&... args)
     242              :     {
     243              :         return flags.mValue | Or(std::forward<Args>(args)...);
     244              :     }
     245        53087 :     static constexpr IntegerType Or(FlagsEnum value) { return static_cast<IntegerType>(value); }
     246         1795 :     static constexpr IntegerType Or(const BitFlags<FlagsEnum> & flags) { return flags.Raw(); }
     247              : 
     248              :     StorageType mValue = 0;
     249              : };
     250              : 
     251              : } // namespace chip
        

Generated by: LCOV version 2.0-1