Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
test_darray_01.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <cassert>
25#include <cinttypes>
26#include <cstring>
27#include <random>
28#include <vector>
29
31
32#include "test_datatype01.hpp"
33
34#include "test_datatype02.hpp"
35
36#include <jau/basic_algos.hpp>
37#include <jau/basic_types.hpp>
38#include <jau/darray.hpp>
40#include <jau/callocator.hpp>
42
43/**
44 * Test general use of jau::darray, jau::cow_darray and jau::cow_vector.
45 */
46using namespace jau;
47
48/**********************************************************************************************************************************************/
49/**********************************************************************************************************************************************/
50/**********************************************************************************************************************************************/
51/**********************************************************************************************************************************************/
52/**********************************************************************************************************************************************/
53
54TEST_CASE( "JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]" ) {
55 int i = 0;
57 (void)ml;
58 // printf("XX: %s\n\n", ml->toString().c_str());
59 ++i;
60 });
61 REQUIRE(3 == i);
62}
63
65 int i = 0;
66 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
67 (void)ml;
68 // printf("XX: %s\n\n", ml->toString().c_str());
69 ++i;
70 });
71 return i;
72}
74 int i = 0;
75 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
76 (void)ml;
77 // printf("XX: %s\n\n", ml->toString().c_str());
78 ++i;
79 });
80 return i;
81}
82
83TEST_CASE( "JAU DArray Test 02 - jau::darray immutable type (const)", "[const][jau][darray]" ) {
85 // GattCharacteristicPropertySpec[9]:
86 { { Read, Mandatory },
89 // GattClientCharacteristicConfigSpec:
91 };
93 cs1,
95 // GattCharacteristicPropertySpec[9]:
96 { { Read, Mandatory },
99 // GattClientCharacteristicConfigSpec:
101 } };
102 clist.push_back( cs1 );
103 int i = 0;
104 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
105 (void)ml;
106 // printf("XX: %s\n\n", ml->toString().c_str());
107 ++i;
108 });
109 REQUIRE(3 == i);
111 REQUIRE(3 == countGattCharacteristicSpecList02Copy(clist));
112}
113
114/**********************************************************************************************************************************************/
115/**********************************************************************************************************************************************/
116/**********************************************************************************************************************************************/
117/**********************************************************************************************************************************************/
118/**********************************************************************************************************************************************/
119
120template<class Payload>
122// JAU_TYPENAME_CUE_ALL(SharedPayloadListMemMove)
123
124template<class Payload>
126// JAU_TYPENAME_CUE_ALL(SharedPayloadListDefault)
127
128template<class Payload>
130 int name;
132
133 std::string toString() const noexcept {
134 std::string res = "NSPL-Default-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
135 int i=0;
136 jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
137 if(0<i) {
138 res.append(", ");
139 }
140 res.append("[").append(jau::to_string(e)).append("]");
141 ++i;
142 } );
143 res.append("]");
144 return res;
145 }
146};
147// JAU_TYPENAME_CUE_ALL(NamedSharedPayloadListDefault)
148
149template<class Payload>
151 int name;
153
154 std::string toString() const noexcept {
155 std::string res = "NSPL-MemMove-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
156 int i=0;
157 jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
158 if(0<i) {
159 res.append(", ");
160 }
161 res.append("[").append(jau::to_string(e)).append("]");
162 ++i;
163 } );
164 res.append("]");
165 return res;
166 }
167};
168// JAU_TYPENAME_CUE_ALL(NamedSharedPayloadListMemMove)
169
170template<class Payload>
172// JAU_TYPENAME_CUE_ALL(PayloadListMemMove)
173
174template<class Payload>
176// JAU_TYPENAME_CUE_ALL(PayloadListDefault)
177
178template<class Payload>
180 int name;
182
183 std::string toString() const noexcept {
184 std::string res = "NPL-Default-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
185 int i=0;
186 jau::for_each(payload.cbegin(), payload.cend(), [&](const typename PayloadListDefault<Payload>::value_type & e) {
187 if(0<i) {
188 res += ", ";
189 }
190 res.append("[").append(jau::to_string(e)).append("]");
191 ++i;
192 } );
193 res += "]";
194 return res;
195 }
196};
197// JAU_TYPENAME_CUE_ALL(NamedPayloadListDefault)
198
199template<class Payload>
201 int name;
203
204 std::string toString() const noexcept {
205 std::string res = "NPL-MemMove-"+std::to_string(name)+"[sz"+std::to_string(payload.size())+": ";
206 int i=0;
207 jau::for_each(payload.cbegin(), payload.cend(), [&](const Payload& e) {
208 if(0<i) {
209 res += ", ";
210 }
211 res.append("[").append(jau::to_string(e)).append("]");
212 ++i;
213 } );
214 res += "]";
215 return res;
216 }
217};
218// JAU_TYPENAME_CUE_ALL(NamedPayloadListMemMove)
219
220template<class Payload>
223 int i=0;
224 for(i=0; i<2; i++) {
225 std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
226 data.push_back( sp );
227 }
228 for(i=2; i<4; i++) {
229 std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
230 data.push_back( std::move( sp ) ); // move the less efficient into
231 }
233}
234template<class Payload>
236 printf("XXX1: %s\n", src.toString().c_str());
237 src.payload.pop_back();
238 src.payload.erase(src.payload.cbegin());
239 printf("XXX2: %s\n", src.toString().c_str());
240 return src;
241}
242
243template<class Payload>
246 int i=0;
247 for(i=0; i<2; i++) {
248 std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
249 data.push_back( sp );
250 }
251 for(i=2; i<4; i++) {
252 std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
253 data.push_back( std::move( sp ) ); // move the less efficient into
254 }
256}
257template<class Payload>
260 int i=0;
261 for(i=0; i<2; i++) {
262 Payload sp( name+i ); // copy-elision
263 data.push_back( sp );
264 }
265 for(i=2; i<4; i++) {
266 Payload sp( name+i );
267 data.push_back( std::move( sp ) ); // move the less efficient into
268 }
269 return NamedPayloadListDefault<Payload>{name, data};
270}
271template<class Payload>
274 int i=0;
275 for(i=0; i<2; i++) {
276 Payload sp( name+i ); // copy-elision
277 data.push_back( sp );
278 }
279 for(i=2; i<4; i++) {
280 Payload sp( name+i );
281 data.push_back( std::move( sp ) ); // move the less efficient into
282 }
283 return NamedPayloadListMemMove<Payload>{name, data};
284}
285
286JAU_TYPENAME_CUE_ALL(std::shared_ptr<Addr48Bit>)
288JAU_TYPENAME_CUE_ALL(jau::darray<std::shared_ptr<Addr48Bit>>)
289
293
294#define CHECK_TRAITS 0
295
296template< class Cont >
297static void print_container_info(const std::string& type_id, const Cont &c,
298 std::enable_if_t< jau::is_darray_type<Cont>::value, bool> = true )
299{
300 printf("\nContainer Type %s (a darray, a cow %d):\n - Uses memmove %d (trivially_copyable %d); realloc %d; base_of jau::callocator %d; secmem %d; size %d bytes\n",
301 type_id.c_str(), jau::is_cow_type<Cont>::value,
302 Cont::uses_memmove,
303 std::is_trivially_copyable<typename Cont::value_type>::value,
304 Cont::uses_realloc,
305 std::is_base_of<jau::callocator<typename Cont::value_type>, typename Cont::allocator_type>::value,
306 Cont::uses_secmem,
307 (int)sizeof(c));
308}
309
310template<class Cont>
311static void print_container_info(const std::string& type_id, const Cont &c,
312 std::enable_if_t< !jau::is_darray_type<Cont>::value, bool> = true )
313{
314 printf("\nContainer Type %s (!darray, a cow %d); size %d bytes\n",
315 type_id.c_str(), jau::is_cow_type<Cont>::value, (int)sizeof(c));
316}
317
318
319template<class Payload>
320static void testDArrayValueType(const std::string& type_id) {
321 {
322 // jau::type_cue<Payload>::print(type_id, jau::TypeTraitGroup::ALL);
323 // jau::type_cue<std::shared_ptr<Payload>>::print("std::shared_ptr<"+type_id+">", jau::TypeTraitGroup::ALL);
324 }
325 {
326#if CHECK_TRAITS
327 CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
329 CHECK( true == std::is_trivially_copyable<Payload>::value);
331#endif
332
333 NamedPayloadListDefault<Payload> data = makeNamedPayloadListDefault<Payload>(1);
334 print_container_info("NamedPayloadListDefault<"+type_id+">", data.payload);
335
337 data2.payload.erase(data2.payload.cbegin());
338
340 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
341
342 NamedPayloadListDefault<Payload> data8 = makeNamedPayloadListDefault<Payload>(8);
343 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
344
345 printf("COPY-0: %s\n\n", data.toString().c_str());
346 printf("COPY-1: %s\n\n", data2.toString().c_str());
347 printf("COPY-2: %s\n\n", data3.toString().c_str());
348 printf("COPY+2: %s\n\n", data8.toString().c_str());
349 }
350 {
351#if CHECK_TRAITS
352 CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
354 CHECK( true == std::is_trivially_copyable<Payload>::value);
356#endif
357
358 NamedPayloadListMemMove<Payload> data = makeNamedPayloadListMemMove<Payload>(1);
359 print_container_info("NamedPayloadListMemMove<"+type_id+">", data.payload);
360
362 data2.payload.erase(data2.payload.cbegin());
363
365 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
366
367 NamedPayloadListMemMove<Payload> data8 = makeNamedPayloadListMemMove<Payload>(8);
368 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
369
370 printf("COPY-0: %s\n\n", data.toString().c_str());
371 printf("COPY-1: %s\n\n", data2.toString().c_str());
372 printf("COPY-2: %s\n\n", data3.toString().c_str());
373 printf("COPY+2: %s\n\n", data8.toString().c_str());
374 }
375 {
376#if CHECK_TRAITS
377 CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
379 CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
381#endif
382
383 NamedSharedPayloadListDefault<Payload> data = makeNamedSharedPayloadListDefault<Payload>(1);
384 print_container_info("NamedSharedPayloadListDefault<"+type_id+">", data.payload);
385
387 data2.payload.erase(data2.payload.cbegin());
388
390 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
391
392 NamedSharedPayloadListDefault<Payload> data8 = makeNamedSharedPayloadListDefault<Payload>(8);
393 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
394
395 printf("COPY-0: %s\n\n", data.toString().c_str());
396 printf("COPY-1: %s\n\n", data2.toString().c_str());
397 printf("COPY-2: %s\n\n", data3.toString().c_str());
398 printf("COPY+2: %s\n\n", data8.toString().c_str());
399
401 printf("MODI+2-2: %s\n\n", data8_mod.toString().c_str());
402
403 struct Holder {
405 NamedSharedPayloadListDefault<Payload> & get_ref() { return lala; }
406 NamedSharedPayloadListDefault<Payload> & get_ref2() { lala.payload.pop_back(); return lala; }
407 NamedSharedPayloadListDefault<Payload> get_copy() { return lala; }
408 };
409 Holder holder{ data };
410 NamedSharedPayloadListDefault<Payload> & r1r1 = holder.get_ref();
411 printf("R1R1: %s\n\n", r1r1.toString().c_str());
412
413 NamedSharedPayloadListDefault<Payload> r2c1 = holder.get_ref();
414 printf("R1C1: %s\n\n", r2c1.toString().c_str());
415
416 NamedSharedPayloadListDefault<Payload> c1c2 = holder.get_copy();
417 printf("C1C2: %s\n\n", c1c2.toString().c_str());
418
419 r1r1 = holder.get_ref2();
420 printf("R2R2: %s\n\n", r1r1.toString().c_str());
421 }
422 {
423#if CHECK_TRAITS
424 CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
426 CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
428#endif
429
430 NamedSharedPayloadListMemMove<Payload> data = makeNamedSharedPayloadListMemMove<Payload>(1);
431 print_container_info("NamedSharedPayloadListMemMove<"+type_id+">", data.payload);
432
434 data2.payload.erase(data2.payload.cbegin());
435
437 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
438
439 NamedSharedPayloadListMemMove<Payload> data8 = makeNamedSharedPayloadListMemMove<Payload>(8);
440 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
441
442 printf("COPY-0: %s\n\n", data.toString().c_str());
443 printf("COPY-1: %s\n\n", data2.toString().c_str());
444 printf("COPY-2: %s\n\n", data3.toString().c_str());
445 printf("COPY+2: %s\n\n", data8.toString().c_str());
446 }
447}
448
450 return *GATT_SERVICES[i];
451}
452
454#if CHECK_TRAITS
456 CHECK( true == GattCharacteristicSpecList::uses_realloc);
457
458 CHECK( true == GattCharacteristicSpecList::uses_memmove);
459 CHECK( true == std::is_trivially_copyable<GattCharacteristicSpec>::value);
460#endif
461
463 print_container_info("darray<GattCharacteristicSpec>", gatt2.characteristics);
464
466
467 GattServiceCharacteristic gatt2b = gatt2;
469
470 GattServiceCharacteristic gatt2c(gatt2);
472
473 printf("COPY0-1: %s\n\n", gatt2.toString().c_str());
474 printf("COPY1-2: %s\n\n", gatt2b.toString().c_str());
475 printf("COPY2-3: %s\n\n", gatt2c.toString().c_str());
476}
477
478TEST_CASE( "JAU DArray Test 10 - jau::darray value_type behavior (type traits)", "[datatype][jau][darray]" ) {
479 testDArrayValueType<uint64_t>("uint64_t");
480 testDArrayValueType<Addr48Bit>("Addr48Bit");
481 testDArrayValueType<DataType01>("DataType01");
482 testDArrayValueType<DataType02_Memmove_Secmem>("DataType02");
484}
485
486/**********************************************************************************************************************************************/
487/**********************************************************************************************************************************************/
488/**********************************************************************************************************************************************/
489/**********************************************************************************************************************************************/
490/**********************************************************************************************************************************************/
491
Implementation of a dynamic linear array storage, aka vector.
Definition: darray.hpp:148
constexpr iterator end() noexcept
Definition: darray.hpp:707
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:1124
constexpr const_iterator cbegin() const noexcept
Definition: darray.hpp:705
constexpr iterator begin() noexcept
Definition: darray.hpp:701
constexpr iterator erase(const_iterator pos)
Like std::vector::erase(), removes the elements at pos.
Definition: darray.hpp:940
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
Like std::for_each() of 'algorithm'.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
#define JAU_TYPENAME_CUE_ALL(A)
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition: backtrace.hpp:32
STL namespace.
std::string toString() const noexcept
jau::darray< GattCharacteristicSpec > characteristics
PayloadListDefault< Payload > payload
std::string toString() const noexcept
PayloadListMemMove< Payload > payload
std::string toString() const noexcept
std::string toString() const noexcept
SharedPayloadListDefault< Payload > payload
std::string toString() const noexcept
SharedPayloadListMemMove< Payload > payload
A simple allocator using POSIX C functions: ::malloc(), ::free() and ::realloc().
Definition: callocator.hpp:50
template< class T > is_cow_type<T>::value compile-time Type Trait, determining whether the given temp...
template< class T > is_darray_type<T>::value compile-time Type Trait, determining whether the given t...
Definition: darray.hpp:1453
static int countGattCharacteristicSpecList01ConstRef(const jau::darray< const GattCharacteristicSpec > &clist)
static NamedSharedPayloadListDefault< Payload > makeNamedSharedPayloadListDefault(int name)
static NamedSharedPayloadListMemMove< Payload > makeNamedSharedPayloadListMemMove(int name)
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)
static void testDArrayValueType(const std::string &type_id)
static NamedPayloadListDefault< Payload > makeNamedPayloadListDefault(int name)
static GattServiceCharacteristic returnGattSrvcChar(int i)
static NamedPayloadListMemMove< Payload > makeNamedPayloadListMemMove(int name)
TEST_CASE("JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]")
static NamedSharedPayloadListDefault< Payload > modifyCopyOfNamedSharedPayloadListDefault(NamedSharedPayloadListDefault< Payload > src)
static int countGattCharacteristicSpecList02Copy(jau::darray< const GattCharacteristicSpec > clist)
static void testDArrayGattServiceCharacteristic()
const jau::darray< const GattServiceCharacteristic * > GATT_SERVICES
@ Notify
@ ReliableWriteExt
FIXME: extension?
@ Indicate
@ AuthSignedWrite
@ WriteNoAck
@ Read
@ Broadcast
@ AuxWriteExt
FIXME: extension?
@ WriteWithAck
@ Optional
@ Mandatory
@ Excluded
@ DEVICE_NAME
@ APPEARANCE
int printf(const char *format,...)
Operating Systems predefined macros.