[core] add Equatable class providing overloads of == and != operator (#5029)

This commit adds new class `Equatable` (inherited by other types)
providing overloads of operators `==` and `!=`. The implementation
simply compares all the bytes of two instances of same type to be
equal (using `memcmp`).
This commit is contained in:
Abtin Keshavarzian
2020-06-02 13:36:24 -07:00
committed by Jonathan Hui
parent 2b9e8facba
commit 71575ff76a
9 changed files with 97 additions and 255 deletions
+1
View File
@@ -323,6 +323,7 @@ HEADERS_COMMON = \
common/crc16.hpp \
common/debug.hpp \
common/encoding.hpp \
common/equatable.hpp \
common/extension.hpp \
common/instance.hpp \
common/linked_list.hpp \
+80
View File
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for Equatable class for OpenThread objects.
*/
#ifndef EQUATABLE_HPP_
#define EQUATABLE_HPP_
#include "openthread-core-config.h"
#include <string.h>
namespace ot {
/**
* This template class defines overloads of operators `==` and `!=`.
*
* The `==` implementation simply compares all the bytes of two `Type` instances to be equal (using `memcmp()`).
*
* Users of this class should follow CRTP-style inheritance, i.e., the `Type` class itself should publicly inherit
* from `Equatable<Type>`.
*
*/
template <class Type> class Equatable
{
public:
/**
* This method overloads operator `==` to evaluate whether or not two instances of `Type` are equal.
*
* @param[in] aOther The other `Type` instance to compare with.
*
* @retval TRUE If the two `Type` instances are equal.
* @retval FALSE If the two `Type` instances are not equal.
*
*/
bool operator==(const Type &aOther) const { return memcmp(this, &aOther, sizeof(Type)) == 0; }
/**
* This method overloads operator `!=` to evaluate whether or not two instances of `Type` are equal.
*
* @param[in] aOther The other `Type` instance to compare with.
*
* @retval TRUE If the two `Type` instances are not equal.
* @retval FALSE If the two `Type` instances are equal.
*
*/
bool operator!=(const Type &aOther) const { return !(*this == aOther); }
};
} // namespace ot
#endif // EQUATABLE_HPP_
-10
View File
@@ -63,11 +63,6 @@ void ExtAddress::GenerateRandom(void)
}
#endif
bool ExtAddress::operator==(const ExtAddress &aOther) const
{
return memcmp(m8, aOther.m8, sizeof(ExtAddress)) == 0;
}
ExtAddress::InfoString ExtAddress::ToString(void) const
{
return InfoString("%02x%02x%02x%02x%02x%02x%02x%02x", m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
@@ -97,11 +92,6 @@ Address::InfoString Address::ToString(void) const
: (mType == kTypeNone ? InfoString("None") : InfoString("0x%04x", GetShort()));
}
bool ExtendedPanId::operator==(const ExtendedPanId &aOther) const
{
return memcmp(m8, aOther.m8, sizeof(ExtendedPanId)) == 0;
}
ExtendedPanId::InfoString ExtendedPanId::ToString(void) const
{
return InfoString("%02x%02x%02x%02x%02x%02x%02x%02x", m8[0], m8[1], m8[2], m8[3], m8[4], m8[5], m8[6], m8[7]);
+4 -68
View File
@@ -42,6 +42,7 @@
#include <openthread/link.h>
#include <openthread/thread.h>
#include "common/equatable.hpp"
#include "common/string.hpp"
namespace ot {
@@ -86,7 +87,7 @@ PanId GenerateRandomPanId(void);
*
*/
OT_TOOL_PACKED_BEGIN
class ExtAddress : public otExtAddress
class ExtAddress : public otExtAddress, public Equatable<ExtAddress>
{
public:
enum
@@ -221,28 +222,6 @@ public:
CopyAddress(aBuffer, m8, aByteOrder);
}
/**
* This method evaluates whether or not the Extended Addresses match.
*
* @param[in] aOther The Extended Address to compare.
*
* @retval TRUE If the Extended Addresses match.
* @retval FALSE If the Extended Addresses do not match.
*
*/
bool operator==(const ExtAddress &aOther) const;
/**
* This method evaluates whether or not the Extended Addresses match.
*
* @param[in] aOther The Extended Address to compare.
*
* @retval TRUE If the Extended Addresses do not match.
* @retval FALSE If the Extended Addresses match.
*
*/
bool operator!=(const ExtAddress &aOther) const { return !(*this == aOther); }
/**
* This method converts an address to a string.
*
@@ -447,7 +426,7 @@ private:
*
*/
OT_TOOL_PACKED_BEGIN
class Key : public otMacKey
class Key : public otMacKey, public Equatable<Key>
{
public:
enum
@@ -469,27 +448,6 @@ public:
*/
const uint8_t *GetKey(void) const { return m8; }
/**
* This method evaluates whether or not two keys match.
*
* @param[in] aOtherKey The key to compare with.
*
* @retval TRUE If the key matches the @p aOtherKey.
* @retval FALSE If the key does not match the @p aOtherKey.
*
*/
bool operator==(const Key &aOtherKey) const { return memcmp(m8, aOtherKey.m8, kSize) == 0; }
/**
* This method evaluates whether or not two keys match.
*
* @param[in] aOtherKey The key to compare with.
*
* @retval TRUE If the key does not match @p aOtherKey.
* @retval FALSE If the key does match @p aOtherKey.
*
*/
bool operator!=(const Key &aOtherKey) const { return !(*this == aOtherKey); }
} OT_TOOL_PACKED_END;
/**
@@ -497,7 +455,7 @@ public:
*
*/
OT_TOOL_PACKED_BEGIN
class ExtendedPanId : public otExtendedPanId
class ExtendedPanId : public otExtendedPanId, public Equatable<ExtendedPanId>
{
public:
enum
@@ -517,28 +475,6 @@ public:
*/
void Clear(void) { memset(this, 0, sizeof(*this)); }
/**
* This method evaluates whether or not the Extended PAN Identifiers match.
*
* @param[in] aOther The Extended PAN Id to compare.
*
* @retval TRUE If the Extended PAN Identifiers match.
* @retval FALSE If the Extended PAN Identifiers do not match.
*
*/
bool operator==(const ExtendedPanId &aOther) const;
/**
* This method evaluates whether or not the Extended PAN Identifiers match.
*
* @param[in] aOther The Extended PAN Id to compare.
*
* @retval TRUE If the Extended Addresses do not match.
* @retval FALSE If the Extended Addresses match.
*
*/
bool operator!=(const ExtendedPanId &aOther) const { return !(*this == aOther); }
/**
* This method converts an address to a string.
*
-5
View File
@@ -320,11 +320,6 @@ uint8_t Address::PrefixMatch(const otIp6Address &aOther) const
return PrefixMatch(mFields.m8, aOther.mFields.m8, sizeof(Address));
}
bool Address::operator==(const Address &aOther) const
{
return memcmp(mFields.m8, aOther.mFields.m8, sizeof(mFields.m8)) == 0;
}
otError Address::FromString(const char *aBuf)
{
otError error = OT_ERROR_NONE;
+2 -23
View File
@@ -39,6 +39,7 @@
#include <stdint.h>
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "common/string.hpp"
#include "mac/mac_types.hpp"
#include "thread/mle_types.hpp"
@@ -60,7 +61,7 @@ namespace Ip6 {
*
*/
OT_TOOL_PACKED_BEGIN
class Address : public otIp6Address
class Address : public otIp6Address, public Equatable<Address>
{
public:
/**
@@ -514,28 +515,6 @@ public:
*/
uint8_t PrefixMatch(const otIp6Address &aOther) const;
/**
* This method evaluates whether or not the IPv6 addresses match.
*
* @param[in] aOther The IPv6 address to compare.
*
* @retval TRUE If the IPv6 addresses match.
* @retval FALSE If the IPv6 addresses do not match.
*
*/
bool operator==(const Address &aOther) const;
/**
* This method evaluates whether or not the IPv6 addresses differ.
*
* @param[in] aOther The IPv6 address to compare.
*
* @retval TRUE If the IPv6 addresses differ.
* @retval FALSE If the IPv6 addresses do not differ.
*
*/
bool operator!=(const Address &aOther) const { return !(*this == aOther); }
/**
* This method converts an IPv6 address string to binary.
*
+3 -47
View File
@@ -40,6 +40,7 @@
#include <openthread/dataset.h>
#include "common/equatable.hpp"
#include "common/locator.hpp"
#include "common/random.hpp"
#include "common/timer.hpp"
@@ -63,31 +64,8 @@ namespace ot {
*
*/
OT_TOOL_PACKED_BEGIN
class MasterKey : public otMasterKey
class MasterKey : public otMasterKey, public Equatable<MasterKey>
{
public:
/**
* This method evaluates whether or not the Thread Master Keys match.
*
* @param[in] aOther The Thread Master Key to compare.
*
* @retval TRUE If the Thread Master Keys match.
* @retval FALSE If the Thread Master Keys do not match.
*
*/
bool operator==(const MasterKey &aOther) const { return memcmp(m8, aOther.m8, sizeof(MasterKey)) == 0; }
/**
* This method evaluates whether or not the Thread Master Keys match.
*
* @param[in] aOther The Thread Master Key to compare.
*
* @retval TRUE If the Thread Master Keys do not match.
* @retval FALSE If the Thread Master Keys match.
*
*/
bool operator!=(const MasterKey &aOther) const { return !(*this == aOther); }
} OT_TOOL_PACKED_END;
/**
@@ -95,7 +73,7 @@ public:
*
*/
OT_TOOL_PACKED_BEGIN
class Pskc : public otPskc
class Pskc : public otPskc, public Equatable<Pskc>
{
public:
/**
@@ -104,28 +82,6 @@ public:
*/
void Clear(void) { memset(this, 0, sizeof(*this)); }
/**
* This method evaluates whether or not the Thread PSKc values match.
*
* @param[in] aOther The Thread PSKc to compare.
*
* @retval TRUE If the Thread PSKc values match.
* @retval FALSE If the Thread PSKc values do not match.
*
*/
bool operator==(const Pskc &aOther) const { return memcmp(m8, aOther.m8, sizeof(Pskc)) == 0; }
/**
* This method evaluates whether or not the Thread PSKc values match.
*
* @param[in] aOther The Thread PSKc to compare.
*
* @retval TRUE If the Thread PSKc values do not match.
* @retval FALSE If the Thread PSKc values match.
*
*/
bool operator!=(const Pskc &aOther) const { return !(*this == aOther); }
#if !OPENTHREAD_RADIO
/**
* This method generates a cryptographically secure random sequence to populate the Thread PSKc.
+4 -72
View File
@@ -43,6 +43,7 @@
#include <openthread/thread.h>
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "common/string.hpp"
#include "mac/mac_types.hpp"
@@ -265,7 +266,7 @@ enum
* This type represents a MLE device mode.
*
*/
class DeviceMode
class DeviceMode : public Equatable<DeviceMode>
{
public:
enum
@@ -407,28 +408,6 @@ public:
*/
bool IsValid(void) const { return !IsFullThreadDevice() || IsRxOnWhenIdle(); }
/**
* This method overloads operator `==` to evaluate whether or not two device modes are equal
*
* @param[in] aOther The other device mode to compare with.
*
* @retval TRUE If the device modes are equal.
* @retval FALSE If the device modes are not equal.
*
*/
bool operator==(const DeviceMode &aOther) const { return (mMode == aOther.mMode); }
/**
* This method overloads operator `!=` to evaluate whether or not two device modes are not equal.
*
* @param[in] aOther The other device mode to compare with.
*
* @retval TRUE If the device modes are not equal.
* @retval FALSE If the device modes are equal.
*
*/
bool operator!=(const DeviceMode &aOther) const { return !(*this == aOther); }
/**
* This method converts the device mode into a human-readable string.
*
@@ -446,7 +425,7 @@ private:
*
*/
OT_TOOL_PACKED_BEGIN
class MeshLocalPrefix : public otMeshLocalPrefix
class MeshLocalPrefix : public otMeshLocalPrefix, public Equatable<MeshLocalPrefix>
{
public:
enum
@@ -455,28 +434,6 @@ public:
kLength = OT_MESH_LOCAL_PREFIX_SIZE * CHAR_BIT, ///< Length of Mesh Local Prefix in bits.
};
/**
* This method evaluates whether or not two Mesh Local Prefixes match.
*
* @param[in] aOther The Mesh Local Prefix to compare.
*
* @retval TRUE If the Mesh Local Prefixes match.
* @retval FALSE If the Mesh Local Prefixes do not match.
*
*/
bool operator==(const MeshLocalPrefix &aOther) const { return memcmp(m8, aOther.m8, sizeof(*this)) == 0; }
/**
* This method evaluates whether or not two Mesh Local Prefixes match.
*
* @param[in] aOther The Mesh Local Prefix to compare.
*
* @retval TRUE If the Mesh Local Prefixes do not match.
* @retval FALSE If the Mesh Local Prefixes match.
*
*/
bool operator!=(const MeshLocalPrefix &aOther) const { return !(*this == aOther); }
/**
* This method derives and sets the Mesh Local Prefix from an Extended PAN ID.
*
@@ -582,7 +539,7 @@ public:
};
OT_TOOL_PACKED_BEGIN
class RouterIdSet
class RouterIdSet : public Equatable<RouterIdSet>
{
public:
/**
@@ -618,31 +575,6 @@ public:
*/
void Remove(uint8_t aRouterId) { mRouterIdSet[aRouterId / 8] &= ~(0x80 >> (aRouterId % 8)); }
/**
* This method returns whether or not the Router ID sets are equal.
*
* @param[in] aOther The other Router ID Set to compare with.
*
* @retval TRUE If the Router ID sets are equal.
* @retval FALSE If the Router ID sets are not equal.
*
*/
bool operator==(const RouterIdSet &aOther) const
{
return memcmp(mRouterIdSet, aOther.mRouterIdSet, sizeof(mRouterIdSet)) == 0;
}
/**
* This method returns whether or not the Router ID sets are not equal.
*
* @param[in] aOther The other Router ID Set to compare with.
*
* @retval TRUE If the Router ID sets are not equal.
* @retval FALSE If the Router ID sets are equal.
*
*/
bool operator!=(const RouterIdSet &aOther) const { return !(*this == aOther); }
private:
uint8_t mRouterIdSet[BitVectorBytes(Mle::kMaxRouterId + 1)];
} OT_TOOL_PACKED_END;
+3 -30
View File
@@ -40,6 +40,7 @@
#include "common/debug.hpp"
#include "common/encoding.hpp"
#include "common/equatable.hpp"
#include "net/ip6_address.hpp"
namespace ot {
@@ -223,7 +224,7 @@ private:
*
*/
OT_TOOL_PACKED_BEGIN
class HasRouteEntry
class HasRouteEntry : public Equatable<HasRouteEntry>
{
public:
/**
@@ -288,20 +289,6 @@ public:
*/
const HasRouteEntry *GetNext(void) const { return (this + 1); }
/**
* This method indicates whether two entries fully match.
*
* @param[in] aOtherEntry Another entry to compare with it.
*
* @retval TRUE The two entries are equal.
* @retval FALSE The two entries are not equal.
*
*/
bool operator==(const HasRouteEntry &aOtherEntry) const
{
return (memcmp(this, &aOtherEntry, sizeof(HasRouteEntry)) == 0);
}
private:
enum
{
@@ -559,7 +546,7 @@ private:
*
*/
OT_TOOL_PACKED_BEGIN
class BorderRouterEntry
class BorderRouterEntry : public Equatable<BorderRouterEntry>
{
public:
enum
@@ -730,20 +717,6 @@ public:
*/
const BorderRouterEntry *GetNext(void) const { return (this + 1); }
/**
* This method indicates whether two entries fully match.
*
* @param[in] aOtherEntry Another entry to compare with it.
*
* @retval TRUE The two entries are equal.
* @retval FALSE The two entries are not equal.
*
*/
bool operator==(const BorderRouterEntry &aOtherEntry) const
{
return (memcmp(this, &aOtherEntry, sizeof(BorderRouterEntry)) == 0);
}
private:
uint16_t mRloc;
uint16_t mFlags;