Direct-BT  2.3.1
Direct-BT - Direct Bluetooth Programming.
test_cow_darray_01.cpp

This C++ unit test validates the jau::cow_darray implementation.

/*
* Author: Sven Gothel <sgothel@jausoft.com>
* Copyright (c) 2020 Gothel Software e.K.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <iostream>
#include <cassert>
#include <cinttypes>
#include <cstring>
#include <random>
#include <vector>
#define CATCH_CONFIG_RUNNER
// #define CATCH_CONFIG_MAIN
#include <catch2/catch_amalgamated.hpp>
#include <jau/darray.hpp>
/**
* Test general use of jau::darray, jau::cow_darray and jau::cow_vector.
*/
using namespace jau;
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
TEST_CASE( "JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]" ) {
int i = 0;
(void)ml;
// printf("XX: %s\n\n", ml->toString().c_str());
++i;
});
REQUIRE(3 == i);
}
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
template<class Payload>
// JAU_TYPENAME_CUE_ALL(SharedPayloadListMemMove)
template<class Payload>
// JAU_TYPENAME_CUE_ALL(SharedPayloadListDefault)
template<class Payload>
int name;
std::string toString() const noexcept {
std::string res = "NSPL-Default-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
int i=0;
jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
if(0<i) {
res += ", ";
}
res += "["+jau::to_string(e)+"]";
++i;
} );
res += "]";
return res;
}
};
// JAU_TYPENAME_CUE_ALL(NamedSharedPayloadListDefault)
template<class Payload>
int name;
std::string toString() const noexcept {
std::string res = "NSPL-MemMove-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
int i=0;
jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
if(0<i) {
res += ", ";
}
res += "["+jau::to_string(e)+"]";
++i;
} );
res += "]";
return res;
}
};
// JAU_TYPENAME_CUE_ALL(NamedSharedPayloadListMemMove)
template<class Payload>
using PayloadListMemMove = jau::darray<Payload, jau::callocator<Payload>, jau::nsize_t, true /* use_memmove */, true /* use_realloc */>;
// JAU_TYPENAME_CUE_ALL(PayloadListMemMove)
template<class Payload>
// JAU_TYPENAME_CUE_ALL(PayloadListDefault)
template<class Payload>
int name;
std::string toString() const noexcept {
std::string res = "NPL-Default-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
int i=0;
jau::for_each(payload.cbegin(), payload.cend(), [&](const typename PayloadListDefault<Payload>::value_type & e) {
if(0<i) {
res += ", ";
}
res += "["+jau::to_string(e)+"]";
++i;
} );
res += "]";
return res;
}
};
// JAU_TYPENAME_CUE_ALL(NamedPayloadListDefault)
template<class Payload>
int name;
std::string toString() const noexcept {
std::string res = "NPL-MemMove-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
int i=0;
jau::for_each(payload.cbegin(), payload.cend(), [&](const Payload& e) {
if(0<i) {
res += ", ";
}
res += "["+jau::to_string(e)+"]";
++i;
} );
res += "]";
return res;
}
};
// JAU_TYPENAME_CUE_ALL(NamedPayloadListMemMove)
template<class Payload>
int i=0;
for(i=0; i<2; i++) {
std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
data.push_back( sp );
}
for(i=2; i<4; i++) {
std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
data.push_back( std::move( sp ) ); // move the less efficient into
}
}
template<class Payload>
printf("XXX1: %s\n", src.toString().c_str());
src.payload.pop_back();
src.payload.erase(src.payload.cbegin());
printf("XXX2: %s\n", src.toString().c_str());
return src;
}
template<class Payload>
int i=0;
for(i=0; i<2; i++) {
std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
data.push_back( sp );
}
for(i=2; i<4; i++) {
std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
data.push_back( std::move( sp ) ); // move the less efficient into
}
}
template<class Payload>
int i=0;
for(i=0; i<2; i++) {
Payload sp( name+i ); // copy-elision
data.push_back( sp );
}
for(i=2; i<4; i++) {
Payload sp( name+i );
data.push_back( std::move( sp ) ); // move the less efficient into
}
}
template<class Payload>
int i=0;
for(i=0; i<2; i++) {
Payload sp( name+i ); // copy-elision
data.push_back( sp );
}
for(i=2; i<4; i++) {
Payload sp( name+i );
data.push_back( std::move( sp ) ); // move the less efficient into
}
}
JAU_TYPENAME_CUE_ALL(std::shared_ptr<Addr48Bit>)
JAU_TYPENAME_CUE_ALL(jau::darray<std::shared_ptr<Addr48Bit>>)
#define CHECK_TRAITS 0
template< class Cont >
static void print_container_info(const std::string& type_id, const Cont &c,
std::enable_if_t< jau::is_darray_type<Cont>::value, bool> = true )
{
printf("\nContainer Type %s (a darray, a cow %d):\n - Uses memcpy %d (trivially_copyable %d); realloc %d; base_of jau::callocator %d; size %d bytes\n",
Cont::uses_memmove,
std::is_trivially_copyable<typename Cont::value_type>::value,
Cont::uses_realloc,
std::is_base_of<jau::callocator<typename Cont::value_type>, typename Cont::allocator_type>::value,
(int)sizeof(c));
}
template<class Cont>
static void print_container_info(const std::string& type_id, const Cont &c,
std::enable_if_t< !jau::is_darray_type<Cont>::value, bool> = true )
{
printf("\nContainer Type %s (!darray, a cow %d); size %d bytes\n",
type_id.c_str(), jau::is_cow_type<Cont>::value, (int)sizeof(c));
}
template<class Payload>
static void testDArrayValueType(const std::string& type_id) {
{
// jau::type_cue<Payload>::print(type_id, jau::TypeTraitGroup::ALL);
// jau::type_cue<std::shared_ptr<Payload>>::print("std::shared_ptr<"+type_id+">", jau::TypeTraitGroup::ALL);
}
{
#if CHECK_TRAITS
CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
CHECK( true == std::is_trivially_copyable<Payload>::value);
#endif
NamedPayloadListDefault<Payload> data = makeNamedPayloadListDefault<Payload>(1);
print_container_info("NamedPayloadListDefault<"+type_id+">", data.payload);
data2.payload.erase(data2.payload.cbegin());
data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
NamedPayloadListDefault<Payload> data8 = makeNamedPayloadListDefault<Payload>(8);
data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
printf("COPY-0: %s\n\n", data.toString().c_str());
printf("COPY-1: %s\n\n", data2.toString().c_str());
printf("COPY-2: %s\n\n", data3.toString().c_str());
printf("COPY+2: %s\n\n", data8.toString().c_str());
}
{
#if CHECK_TRAITS
CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
CHECK( true == std::is_trivially_copyable<Payload>::value);
#endif
NamedPayloadListMemMove<Payload> data = makeNamedPayloadListMemMove<Payload>(1);
print_container_info("NamedPayloadListMemMove<"+type_id+">", data.payload);
data2.payload.erase(data2.payload.cbegin());
data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
NamedPayloadListMemMove<Payload> data8 = makeNamedPayloadListMemMove<Payload>(8);
data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
printf("COPY-0: %s\n\n", data.toString().c_str());
printf("COPY-1: %s\n\n", data2.toString().c_str());
printf("COPY-2: %s\n\n", data3.toString().c_str());
printf("COPY+2: %s\n\n", data8.toString().c_str());
}
{
#if CHECK_TRAITS
CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
#endif
NamedSharedPayloadListDefault<Payload> data = makeNamedSharedPayloadListDefault<Payload>(1);
print_container_info("NamedSharedPayloadListDefault<"+type_id+">", data.payload);
data2.payload.erase(data2.payload.cbegin());
data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
NamedSharedPayloadListDefault<Payload> data8 = makeNamedSharedPayloadListDefault<Payload>(8);
data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
printf("COPY-0: %s\n\n", data.toString().c_str());
printf("COPY-1: %s\n\n", data2.toString().c_str());
printf("COPY-2: %s\n\n", data3.toString().c_str());
printf("COPY+2: %s\n\n", data8.toString().c_str());
printf("MODI+2-2: %s\n\n", data8_mod.toString().c_str());
struct Holder {
NamedSharedPayloadListDefault<Payload> & get_ref() { return lala; }
NamedSharedPayloadListDefault<Payload> & get_ref2() { lala.payload.pop_back(); return lala; }
NamedSharedPayloadListDefault<Payload> get_copy() { return lala; }
};
Holder holder{ data };
NamedSharedPayloadListDefault<Payload> & r1r1 = holder.get_ref();
printf("R1R1: %s\n\n", r1r1.toString().c_str());
NamedSharedPayloadListDefault<Payload> r2c1 = holder.get_ref();
printf("R1C1: %s\n\n", r2c1.toString().c_str());
NamedSharedPayloadListDefault<Payload> c1c2 = holder.get_copy();
printf("C1C2: %s\n\n", c1c2.toString().c_str());
r1r1 = holder.get_ref2();
printf("R2R2: %s\n\n", r1r1.toString().c_str());
}
{
#if CHECK_TRAITS
CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
#endif
NamedSharedPayloadListMemMove<Payload> data = makeNamedSharedPayloadListMemMove<Payload>(1);
print_container_info("NamedSharedPayloadListMemMove<"+type_id+">", data.payload);
data2.payload.erase(data2.payload.cbegin());
data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
NamedSharedPayloadListMemMove<Payload> data8 = makeNamedSharedPayloadListMemMove<Payload>(8);
data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
printf("COPY-0: %s\n\n", data.toString().c_str());
printf("COPY-1: %s\n\n", data2.toString().c_str());
printf("COPY-2: %s\n\n", data3.toString().c_str());
printf("COPY+2: %s\n\n", data8.toString().c_str());
}
}
return *GATT_SERVICES[i];
}
#if CHECK_TRAITS
CHECK( true == GattCharacteristicSpecList::uses_realloc);
CHECK( true == GattCharacteristicSpecList::uses_memmove);
CHECK( true == std::is_trivially_copyable<GattCharacteristicSpec>::value);
#endif
print_container_info("darray<GattCharacteristicSpec>", gatt2.characteristics);
GattServiceCharacteristic gatt2b = gatt2;
gatt2c.characteristics.erase(gatt2c.characteristics.cbegin());
printf("COPY0-1: %s\n\n", gatt2.toString().c_str());
printf("COPY1-2: %s\n\n", gatt2b.toString().c_str());
printf("COPY2-3: %s\n\n", gatt2c.toString().c_str());
}
TEST_CASE( "JAU DArray Test 02 - jau::darray value_type behavior (type traits)", "[datatype][jau][darray]" ) {
testDArrayValueType<uint64_t>("uint64_t");
testDArrayValueType<Addr48Bit>("Addr48Bit");
testDArrayValueType<DataType01>("DataType01");
}
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
/**********************************************************************************************************************************************/
GattServiceCharacteristic::toString
std::string toString() const noexcept
Definition: test_datatype02.hpp:442
callocator.hpp
NamedPayloadListDefault::name
int name
Definition: test_cow_darray_01.cpp:136
darray.hpp
NamedPayloadListMemMove
Definition: test_cow_darray_01.cpp:156
test_datatype02.hpp
TEST_CASE
TEST_CASE("JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]")
Definition: test_cow_darray_01.cpp:60
counting_callocator.hpp
basic_algos.hpp
NamedSharedPayloadListDefault::toString
std::string toString() const noexcept
Definition: test_cow_darray_01.cpp:89
jau::is_darray_type
template< class T > is_darray_type<T>::value compile-time Type Trait, determining whether the given t...
Definition: darray.hpp:1206
NamedSharedPayloadListMemMove::name
int name
Definition: test_cow_darray_01.cpp:107
makeNamedPayloadListMemMove
static NamedPayloadListMemMove< Payload > makeNamedPayloadListMemMove(int name)
Definition: test_cow_darray_01.cpp:228
jau::darray::cbegin
constexpr const_iterator cbegin() const noexcept
Definition: darray.hpp:610
jau::for_each
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
Like std::for_each() of 'algorithm'.
Definition: basic_algos.hpp:163
jau
Definition: basic_algos.hpp:34
NamedSharedPayloadListDefault
Definition: test_cow_darray_01.cpp:85
jau::is_cow_type
template< class T > is_cow_type<T>::value compile-time Type Trait, determining whether the given temp...
Definition: cow_iterator.hpp:1039
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
jau::darray
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:102
jau::darray::push_back
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:991
cow_darray.hpp
test_datatype01.hpp
makeNamedPayloadListDefault
static NamedPayloadListDefault< Payload > makeNamedPayloadListDefault(int name)
Definition: test_cow_darray_01.cpp:214
NamedPayloadListMemMove::payload
PayloadListMemMove< Payload > payload
Definition: test_cow_darray_01.cpp:158
cow_vector.hpp
GATT_SERVICES
const jau::darray< const GattServiceCharacteristic * > GATT_SERVICES
Definition: test_datatype02.hpp:334
returnGattSrvcChar
static GattServiceCharacteristic returnGattSrvcChar(int i)
Definition: test_cow_darray_01.cpp:404
jau::darray< Payload >::value_type
Payload value_type
Definition: darray.hpp:113
JAU_TYPENAME_CUE_ALL
#define JAU_TYPENAME_CUE_ALL(A)
Definition: type_traits_queries.hpp:223
NamedPayloadListMemMove::name
int name
Definition: test_cow_darray_01.cpp:157
NamedPayloadListDefault::toString
std::string toString() const noexcept
Definition: test_cow_darray_01.cpp:139
NamedSharedPayloadListMemMove
Definition: test_cow_darray_01.cpp:106
jau::darray::size
constexpr size_type size() const noexcept
Like std::vector::size().
Definition: darray.hpp:668
counting_allocator.hpp
makeNamedSharedPayloadListMemMove
static NamedSharedPayloadListMemMove< Payload > makeNamedSharedPayloadListMemMove(int name)
Definition: test_cow_darray_01.cpp:200
NamedSharedPayloadListMemMove::payload
SharedPayloadListMemMove< Payload > payload
Definition: test_cow_darray_01.cpp:108
NamedPayloadListDefault
Definition: test_cow_darray_01.cpp:135
GattServiceCharacteristic::characteristics
jau::darray< GattCharacteristicSpec > characteristics
Definition: test_datatype02.hpp:174
NamedPayloadListDefault::payload
PayloadListDefault< Payload > payload
Definition: test_cow_darray_01.cpp:137
NamedPayloadListMemMove::toString
std::string toString() const noexcept
Definition: test_cow_darray_01.cpp:160
NamedSharedPayloadListDefault::payload
SharedPayloadListDefault< Payload > payload
Definition: test_cow_darray_01.cpp:87
jau::nsize_t
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:44
testDArrayGattServiceCharacteristic
static void testDArrayGattServiceCharacteristic()
Definition: test_cow_darray_01.cpp:408
DataType01
Definition: test_datatype01.hpp:141
jau::callocator
A simple allocator using POSIX C functions: ::malloc(), ::free() and ::realloc().
Definition: callocator.hpp:53
testDArrayValueType
static void testDArrayValueType(const std::string &type_id)
Definition: test_cow_darray_01.cpp:275
print_container_info
static void print_container_info(const std::string &type_id, const Cont &c, std::enable_if_t< jau::is_darray_type< Cont >::value, bool >=true)
Definition: test_cow_darray_01.cpp:253
modifyCopyOfNamedSharedPayloadListDefault
static NamedSharedPayloadListDefault< Payload > modifyCopyOfNamedSharedPayloadListDefault(NamedSharedPayloadListDefault< Payload > src)
Definition: test_cow_darray_01.cpp:191
makeNamedSharedPayloadListDefault
static NamedSharedPayloadListDefault< Payload > makeNamedSharedPayloadListDefault(int name)
Definition: test_cow_darray_01.cpp:177
basic_types.hpp
catch2_ext.hpp
GattServiceCharacteristic
Definition: test_datatype02.hpp:172
jau::darray::erase
constexpr iterator erase(const_iterator pos)
Like std::vector::erase(), removes the elements at pos.
Definition: darray.hpp:832
NamedSharedPayloadListMemMove::toString
std::string toString() const noexcept
Definition: test_cow_darray_01.cpp:110
jau::darray::cend
constexpr const_iterator cend() const noexcept
Definition: darray.hpp:616