Matter SDK Coverage Report
Current view: top level - app/data-model - Nullable.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 64.3 % 14 9
Test Date: 2025-01-17 19:00:11 Functions: 35.0 % 40 14

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020-2021 Project CHIP Authors
       4              :  *    All rights reserved.
       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              : #pragma once
      20              : 
      21              : #include <app/util/attribute-storage-null-handling.h>
      22              : #include <optional>
      23              : #include <type_traits>
      24              : #include <utility>
      25              : 
      26              : namespace chip {
      27              : namespace app {
      28              : namespace DataModel {
      29              : 
      30              : /**
      31              :  * NullNullable is an alias for NullOptional, for better readability.
      32              :  */
      33              : inline constexpr auto NullNullable = NullOptional;
      34              : 
      35              : /*
      36              :  * Dedicated type for nullable things, to differentiate them from optional
      37              :  * things.
      38              :  */
      39              : template <typename T>
      40              : struct Nullable : protected std::optional<T>
      41              : {
      42              : 
      43              :     //
      44              :     // The following 'using' statement is needed to make visible
      45              :     // all constructors of the base class within this derived class.
      46              :     //
      47              :     using std::optional<T>::optional;
      48              : 
      49              :     // Do NOT pull in optional::operator* or optional::operator->, because that
      50              :     // leads people to write code that looks like it should work, and compiles,
      51              :     // but does not do the right things with TLV encoding and decoding, when
      52              :     // nullable data model objects are involved.
      53              : 
      54         5542 :     Nullable(NullOptionalType) : std::optional<T>(std::nullopt) {}
      55              : 
      56              :     // Some consumers need an easy way to determine our underlying type.
      57              :     using UnderlyingType = T;
      58              : 
      59          121 :     constexpr void SetNull() { std::optional<T>::reset(); }
      60          326 :     constexpr bool IsNull() const { return !std::optional<T>::has_value(); }
      61              : 
      62              :     template <class... Args>
      63            0 :     constexpr T & SetNonNull(Args &&... args)
      64              :     {
      65            0 :         return std::optional<T>::emplace(std::forward<Args>(args)...);
      66              :     }
      67              : 
      68              :     template <typename... Args>
      69              :     constexpr auto ValueOr(Args &&... args) const
      70              :     {
      71              :         return std::optional<T>::value_or(std::forward<Args>(args)...);
      72              :     }
      73              : 
      74           31 :     inline constexpr const T & Value() const { return std::optional<T>::value(); }
      75            0 :     inline T & Value() { return std::optional<T>::value(); }
      76              : 
      77              :     // For integer types, being nullable involves a range restriction.
      78              :     template <
      79              :         typename U = std::decay_t<T>,
      80              :         typename std::enable_if_t<(std::is_integral<U>::value && !std::is_same<U, bool>::value) || std::is_enum<U>::value, int> = 0>
      81              :     constexpr bool ExistingValueInEncodableRange() const
      82              :     {
      83              :         return NumericAttributeTraits<T>::CanRepresentValue(/* isNullable = */ true, Value());
      84              :     }
      85              : 
      86              :     // For all other types, all values are valid.
      87              :     template <typename U                     = std::decay_t<T>,
      88              :               typename std::enable_if_t<(!std::is_integral<U>::value || std::is_same<U, bool>::value) && !std::is_enum<U>::value,
      89              :                                         int> = 0>
      90            0 :     constexpr bool ExistingValueInEncodableRange() const
      91              :     {
      92            0 :         return true;
      93              :     }
      94              : 
      95              :     // Set the nullable to the `other` nullable, returning true if something actually changed.
      96              :     // This can be used to determine if changes occurred on assignment, so that reporting can be triggered
      97              :     // only on actual changes.
      98              :     constexpr bool Update(const Nullable<T> & other)
      99              :     {
     100              :         bool changed = *this != other;
     101              :         if (changed)
     102              :         {
     103              :             *this = other;
     104              :         }
     105              :         return changed;
     106              :     }
     107              : 
     108              :     // The only fabric-scoped objects in the spec are commands, events and structs inside lists, and none of those can be nullable.
     109              :     static constexpr bool kIsFabricScoped = false;
     110              : 
     111              :     inline bool operator==(const T & other) const { return static_cast<const std::optional<T> &>(*this) == other; }
     112              :     inline bool operator!=(const T & other) const { return !(*this == other); }
     113              : 
     114           19 :     inline bool operator==(const Nullable<T> & other) const
     115              :     {
     116           19 :         return static_cast<const std::optional<T> &>(*this) == static_cast<const std::optional<T> &>(other);
     117              :     }
     118           14 :     inline bool operator!=(const Nullable<T> & other) const { return !(*this == other); }
     119              : };
     120              : 
     121              : template <class T>
     122            4 : constexpr Nullable<std::decay_t<T>> MakeNullable(T && value)
     123              : {
     124            4 :     return Nullable<std::decay_t<T>>(std::in_place, std::forward<T>(value));
     125              : }
     126              : 
     127              : template <class T, class... Args>
     128              : constexpr Nullable<T> MakeNullable(Args &&... args)
     129              : {
     130              :     return Nullable<T>(std::in_place, std::forward<Args>(args)...);
     131              : }
     132              : 
     133              : } // namespace DataModel
     134              : } // namespace app
     135              : } // namespace chip
        

Generated by: LCOV version 2.0-1