Skip to content

Commit 663921d

Browse files
authored
WIP: Template Singleton make_ functions (#132)
* Template NoteTxn Singleton `make_` function * Template NoteLog Singleton `make_` function * Template NoteI2c Singleton `make_` function
1 parent 2efe303 commit 663921d

17 files changed

+188
-90
lines changed

src/NoteI2c.hpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
class NoteI2c
88
{
99
public:
10-
/**************************************************************************/
11-
/*!
12-
@brief Type used to abstract specific hardware implementation types.
13-
*/
14-
/**************************************************************************/
15-
typedef void * param_t;
1610

1711
virtual ~NoteI2c(void) {}
1812

@@ -94,8 +88,7 @@ class NoteI2c
9488
the platform specific I2C implementation.
9589
*/
9690
/******************************************************************************/
97-
NoteI2c * make_note_i2c (
98-
NoteI2c::param_t i2c_parameters
99-
);
91+
template <typename T> NoteI2c * make_note_i2c (T & i2c_parameters);
92+
NoteI2c * make_note_i2c (nullptr_t);
10093

10194
#endif // NOTE_I2C_HPP

src/NoteI2c_Arduino.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,37 @@
44
static const char *i2cerr = "i2c {io}";
55
#endif
66

7+
// Singleton instance of the NoteI2c_Arduino class
8+
namespace instance {
9+
inline NoteI2c* & note_i2c (void) {
10+
static NoteI2c* note_i2c = nullptr;
11+
return note_i2c;
12+
}
13+
};
14+
715
NoteI2c *
816
make_note_i2c (
9-
NoteI2c::param_t i2c_parameters_
17+
nullptr_t
18+
) {
19+
NoteI2c* & note_i2c = instance::note_i2c();
20+
if (note_i2c) {
21+
delete note_i2c;
22+
note_i2c = nullptr;
23+
}
24+
return note_i2c;
25+
}
26+
27+
template <typename T>
28+
NoteI2c *
29+
make_note_i2c (
30+
T & i2c_parameters_
1031
)
1132
{
12-
static NoteI2c * note_i2c = nullptr;
13-
if (!i2c_parameters_) {
14-
if (note_i2c) {
15-
delete note_i2c;
16-
note_i2c = nullptr;
17-
}
18-
} else if (!note_i2c) {
19-
note_i2c = new NoteI2c_Arduino(*reinterpret_cast<TwoWire *>(i2c_parameters_));
33+
NoteI2c* & note_i2c = instance::note_i2c();
34+
if (!note_i2c) {
35+
note_i2c = new NoteI2c_Arduino(i2c_parameters_);
2036
}
37+
2138
return note_i2c;
2239
}
2340

@@ -182,3 +199,6 @@ NoteI2c_Arduino::transmit (
182199

183200
return result;
184201
}
202+
203+
// Explicitly instantiate the template function for the supported types
204+
template NoteI2c * make_note_i2c<TwoWire>(TwoWire &);

src/NoteLog.hpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
class NoteLog
77
{
88
public:
9-
/**************************************************************************/
10-
/*!
11-
@brief Type used to abstract specific hardware implementation types.
12-
*/
13-
/**************************************************************************/
14-
typedef void * param_t;
159

1610
virtual ~NoteLog(void) {}
1711

@@ -36,8 +30,7 @@ class NoteLog
3630
the platform specific log output implementation.
3731
*/
3832
/******************************************************************************/
39-
NoteLog * make_note_log (
40-
NoteLog::param_t log_parameters
41-
);
33+
template <typename T> NoteLog * make_note_log (T & log_parameters);
34+
NoteLog * make_note_log (nullptr_t);
4235

4336
#endif // NOTE_LOG_HPP

src/NoteLog_Arduino.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
#include "NoteLog_Arduino.hpp"
22

3+
// Singleton instance of the NoteLog_Arduino class
4+
namespace instance {
5+
inline NoteLog* & note_log (void) {
6+
static NoteLog* note_log = nullptr;
7+
return note_log;
8+
}
9+
};
10+
311
NoteLog *
412
make_note_log (
5-
NoteLog::param_t log_parameters_
6-
)
7-
{
8-
static NoteLog * note_log = nullptr;
9-
if (!log_parameters_) {
10-
if (note_log) {
11-
delete note_log;
12-
note_log = nullptr;
13-
}
14-
} else if (!note_log) {
15-
note_log = new NoteLog_Arduino(reinterpret_cast<Stream *>(log_parameters_));
13+
nullptr_t
14+
) {
15+
NoteLog* & note_log = instance::note_log();
16+
if (note_log) {
17+
delete note_log;
18+
note_log = nullptr;
19+
}
20+
return note_log;
21+
}
22+
23+
template <typename T>
24+
NoteLog *
25+
make_note_log (
26+
T & log_parameters_
27+
) {
28+
NoteLog* & note_log = instance::note_log();
29+
if (!note_log) {
30+
note_log = new NoteLog_Arduino(reinterpret_cast<T *>(&log_parameters_));
1631
}
32+
1733
return note_log;
1834
}
1935

@@ -35,3 +51,6 @@ NoteLog_Arduino::print (
3551

3652
return result;
3753
}
54+
55+
// Explicitly instantiate the template function for the supported types
56+
template NoteLog * make_note_log<Stream>(Stream &);

src/NoteTxn.hpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
class NoteTxn
88
{
99
public:
10-
/**************************************************************************/
11-
/*!
12-
@brief Type used to abstract specific hardware implementation types.
13-
*/
14-
/**************************************************************************/
15-
typedef void * param_t;
1610

1711
virtual ~NoteTxn(void) {}
1812

@@ -44,8 +38,7 @@ class NoteTxn
4438
the platform specific transaction implementation.
4539
*/
4640
/******************************************************************************/
47-
NoteTxn * make_note_txn (
48-
NoteTxn::param_t txn_parameters
49-
);
41+
template<typename T> NoteTxn * make_note_txn (T & txn_parameters);
42+
NoteTxn * make_note_txn (nullptr_t);
5043

5144
#endif // NOTE_TXN_HPP

src/NoteTxn_Arduino.cpp

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,43 @@
77
#include "mock/mock-parameters.hpp"
88
#endif
99

10+
// Singleton instance of the NoteTxn_Arduino class
11+
namespace instance {
12+
inline NoteTxn* & note_txn (void) {
13+
static NoteTxn* note_txn = nullptr;
14+
return note_txn;
15+
}
16+
};
17+
1018
NoteTxn *
1119
make_note_txn (
12-
NoteTxn::param_t txn_parameters_
13-
)
14-
{
15-
static NoteTxn * note_txn = nullptr;
16-
if (!txn_parameters_) {
20+
nullptr_t
21+
) {
22+
NoteTxn* & note_txn = instance::note_txn();
23+
if (note_txn) {
24+
delete note_txn;
25+
note_txn = nullptr;
26+
}
27+
return note_txn;
28+
}
29+
30+
template <typename T>
31+
NoteTxn *
32+
make_note_txn (
33+
T & txn_pins_
34+
) {
35+
NoteTxn* & note_txn = instance::note_txn();
36+
37+
if (txn_pins_[0] == txn_pins_[1]) {
38+
// Invalid tuple invokes deletion
1739
if (note_txn) {
1840
delete note_txn;
1941
note_txn = nullptr;
2042
}
2143
} else if (!note_txn) {
22-
const uint8_t * txn_pins = reinterpret_cast<uint8_t *>(txn_parameters_);
23-
note_txn = new NoteTxn_Arduino(txn_pins[0], txn_pins[1]);
44+
note_txn = new NoteTxn_Arduino(txn_pins_[0], txn_pins_[1]);
2445
}
46+
2547
return note_txn;
2648
}
2749

@@ -80,3 +102,7 @@ NoteTxn_Arduino::stop (
80102
// Float RTX pin
81103
::pinMode(_rtx_pin, INPUT);
82104
}
105+
106+
// Explicitly instantiate the template function for array types
107+
template NoteTxn * make_note_txn<uint8_t[2]>(uint8_t(&)[2]);
108+
template NoteTxn * make_note_txn<const uint8_t[2]>(const uint8_t(&)[2]);

src/Notecard.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class Notecard
6363
inline void begin(uint32_t i2cAddress = NOTE_I2C_ADDR_DEFAULT,
6464
uint32_t i2cMax = NOTE_I2C_MAX_DEFAULT,
6565
TwoWire &wirePort = Wire) {
66-
begin(make_note_i2c(&wirePort), i2cAddress, i2cMax);
66+
begin(make_note_i2c(wirePort), i2cAddress, i2cMax);
6767
}
6868
inline void begin(HardwareSerial &serial, uint32_t speed = 9600) {
6969
MakeNoteSerial_ArduinoParameters<HardwareSerial> arduino_parameters(serial, speed);
@@ -76,7 +76,7 @@ class Notecard
7676
}
7777
#endif
7878
inline void setDebugOutputStream(Stream &dbgserial) {
79-
setDebugOutputStream(make_note_log(&dbgserial));
79+
setDebugOutputStream(make_note_log(dbgserial));
8080
}
8181
inline void setTransactionPins(uint8_t ctx_pin, uint8_t rtx_pin) {
8282
uint8_t txn_pins[2] = {ctx_pin, rtx_pin};

test/NoteI2c_Arduino.test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ int test_make_note_i2c_instantiates_notei2c_object()
1616
NoteI2c * notei2c = nullptr;
1717

1818
// Action
19-
notei2c = make_note_i2c(reinterpret_cast<NoteI2c::param_t>(&Wire));
19+
notei2c = make_note_i2c(Wire);
2020

2121
// Assert
2222
if (nullptr != notei2c)
@@ -42,10 +42,10 @@ int test_make_note_i2c_enforces_singleton_by_returning_same_notei2c_object_for_a
4242
int result;
4343

4444
// Arrange
45-
NoteI2c * const notei2c_1 = make_note_i2c(reinterpret_cast<NoteI2c::param_t>(&Wire));
45+
NoteI2c * const notei2c_1 = make_note_i2c(Wire);
4646

4747
// Action
48-
NoteI2c * const notei2c_2 = make_note_i2c(reinterpret_cast<NoteI2c::param_t>(&Wire));
48+
NoteI2c * const notei2c_2 = make_note_i2c(Wire);
4949

5050
// Assert
5151
if (notei2c_1 == notei2c_2)
@@ -72,7 +72,7 @@ int test_make_note_i2c_deletes_singleton_when_nullptr_is_passed_as_parameter()
7272
int result;
7373

7474
// Arrange
75-
NoteI2c * notei2c = make_note_i2c(reinterpret_cast<NoteI2c::param_t>(&Wire));
75+
NoteI2c * notei2c = make_note_i2c(Wire);
7676
assert(notei2c);
7777

7878
// Action

test/NoteLog_Arduino.test.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ int test_make_note_log_instantiates_notelog_object()
1414

1515
// Arrange
1616
NoteLog * notelog = nullptr;
17+
Stream & serial_stream = Serial;
1718

1819
// Action
19-
notelog = make_note_log(reinterpret_cast<NoteLog::param_t>(&Serial));
20+
notelog = make_note_log(serial_stream);
2021

2122
// Assert
2223
if (nullptr != notelog)
@@ -42,10 +43,11 @@ int test_make_note_log_enforces_singleton_by_returning_same_notelog_object_for_a
4243
int result;
4344

4445
// Arrange
45-
NoteLog * const notelog_1 = make_note_log(reinterpret_cast<NoteLog::param_t>(&Serial));
46+
Stream & serial_stream = Serial;
47+
NoteLog * const notelog_1 = make_note_log(serial_stream);
4648

4749
// Action
48-
NoteLog * const notelog_2 = make_note_log(reinterpret_cast<NoteLog::param_t>(&Serial));
50+
NoteLog * const notelog_2 = make_note_log(serial_stream);
4951

5052
// Assert
5153
if (notelog_1 == notelog_2)
@@ -72,7 +74,8 @@ int test_make_note_log_deletes_singleton_when_nullptr_is_passed_as_parameter()
7274
int result;
7375

7476
// Arrange
75-
NoteLog * notelog = make_note_log(reinterpret_cast<NoteLog::param_t>(&Serial));
77+
Stream & serial_stream = Serial;
78+
NoteLog * notelog = make_note_log(serial_stream);
7679
assert(notelog);
7780

7881
// Action

test/NoteTxn_Arduino.test.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ int test_make_note_txn_instantiates_notetxn_object()
1616
uint8_t txn_pins[2] = {19, 79};
1717

1818
// Action
19-
notetxn = make_note_txn(reinterpret_cast<NoteTxn::param_t>(txn_pins));
19+
notetxn = make_note_txn(txn_pins);
2020

2121
// Assert
2222
if (nullptr != notetxn)
@@ -32,7 +32,8 @@ int test_make_note_txn_instantiates_notetxn_object()
3232
}
3333

3434
// Clean-up
35-
make_note_txn(nullptr);
35+
uint8_t invalid_pins[2] = {0};
36+
make_note_txn(invalid_pins);
3637

3738
return result;
3839
}
@@ -43,11 +44,11 @@ int test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_a
4344

4445
// Arrange
4546
uint8_t txn_pins_1[2] = {19, 79};
46-
NoteTxn * const notetxn_1 = make_note_txn(reinterpret_cast<NoteTxn::param_t>(txn_pins_1));
47+
NoteTxn * const notetxn_1 = make_note_txn(txn_pins_1);
4748

4849
// Action
4950
uint8_t txn_pins_2[2] = {9, 17};
50-
NoteTxn * const notetxn_2 = make_note_txn(reinterpret_cast<NoteTxn::param_t>(txn_pins_2));
51+
NoteTxn * const notetxn_2 = make_note_txn(txn_pins_2);
5152

5253
// Assert
5354
if (notetxn_1 == notetxn_2)
@@ -63,23 +64,25 @@ int test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_a
6364
}
6465

6566
// Clean-up
66-
make_note_txn(nullptr);
67+
uint8_t invalid_pins[2] = {0};
68+
make_note_txn(invalid_pins);
6769

6870
return result;
6971
}
7072

71-
//int test_make_note_txn_returns_nullptr_when_nullptr_is_passed_as_parameter()
72-
int test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter()
73+
//int test_make_note_txn_returns_nullptr_when_same_pins_are_passed_as_parameter()
74+
int test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter()
7375
{
7476
int result;
7577

7678
// Arrange
7779
uint8_t txn_pins[2] = {19, 79};
78-
NoteTxn * notetxn = make_note_txn(reinterpret_cast<NoteTxn::param_t>(txn_pins));
80+
NoteTxn * notetxn = make_note_txn(txn_pins);
7981
assert(notetxn);
8082

8183
// Action
82-
notetxn = make_note_txn(nullptr);
84+
uint8_t invalid_pins[2] = {0};
85+
notetxn = make_note_txn(invalid_pins);
8386

8487
// Assert
8588
if (nullptr == notetxn)
@@ -605,7 +608,7 @@ int main(void)
605608
TestFunction tests[] = {
606609
{test_make_note_txn_instantiates_notetxn_object, "test_make_note_txn_instantiates_notetxn_object"},
607610
{test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_all_calls, "test_make_note_txn_enforces_singleton_by_returning_same_notetxn_object_for_all_calls"},
608-
{test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter, "test_make_note_txn_deletes_singleton_when_nullptr_is_passed_as_parameter"},
611+
{test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter, "test_make_note_txn_deletes_singleton_when_same_pins_are_passed_as_parameter"},
609612
{test_notetxn_arduino_constructor_floats_ctx_pin, "test_notetxn_arduino_constructor_floats_ctx_pin"},
610613
{test_notetxn_arduino_constructor_floats_rtx_pin, "test_notetxn_arduino_constructor_floats_rtx_pin"},
611614
{test_notetxn_arduino_start_initially_configures_ctx_pin_as_input_pullup, "test_notetxn_arduino_start_initially_configures_ctx_pin_as_input_pullup"},

0 commit comments

Comments
 (0)