classData:publicClearable<Data<kDataLengthType>>,publicUnequatable<Data<kDataLengthType>>,privateDataUtils{friendclassMutableData<kDataLengthType>;public:usingLengthType=typenameTypeTraits::Conditional<kDataLengthType==kWithUint8Length,uint8_t,uint16_t>::Type;voidInit(constvoid*aBuffer,LengthTypeaLength){mBuffer=static_cast<constuint8_t*>(aBuffer);mLength=aLength;}voidInitFromRange(constuint8_t*aStart,constuint8_t*aEnd){Init(aStart,static_cast<LengthType>(aEnd-aStart));}template<typenameObjectType>voidInitFrom(constObjectType&aObject){static_assert(!TypeTraits::IsPointer<ObjectType>::kValue,"ObjectType MUST not be a pointer");Init(&aObject,sizeof(aObject));}constuint8_t*GetBytes(void)const{returnmBuffer;}LengthTypeGetLength(void)const{returnmLength;}voidSetLength(LengthTypeaLength){mLength=aLength;}voidCopyBytesTo(void*aBuffer)const{memcpy(aBuffer,mBuffer,mLength);}boolMatchesBytesIn(constvoid*aBuffer)const{returnmemcmp(mBuffer,aBuffer,mLength)==0;}boolMatchesBytesIn(constvoid*aBuffer,ByteMatcheraMatcher){returnMatchBytes(mBuffer,static_cast<constuint8_t*>(aBuffer),mLength,aMatcher);}booloperator==(constData&aOtherData)const{return(mLength==aOtherData.mLength)&&MatchesBytesIn(aOtherData.mBuffer);}boolStartsWith(constData&aOtherData)const{return(mLength>=aOtherData.mLength)&&aOtherData.MatchesBytesIn(mBuffer);}private:constuint8_t*mBuffer;LengthTypemLength;};