36
36
37
37
#define _always_inline __attribute__ ((__always_inline__)) // undefined at end
38
38
39
+
40
+ // Namespace to hide implementation details into. Its contents should
41
+ // not be used outside of this file.
39
42
namespace detail {
40
43
// Returns a value of the given type. No implementation, so this is
41
44
// meant for use in decltype only. Identical to std::declval.
42
45
template <typename T> T declval ();
43
46
44
- // Function that accept a pointer of the given type. Can be used to
45
- // detect if another type is convertible to T.
47
+ // Function that accepts a pointer of the given type. Can be used to
48
+ // detect if another type is convertible to T. No implementation, so
49
+ // intended to be used in declval only.
46
50
template <typename T>
47
51
void accepts_pointer_of_type (const T*);
48
52
49
53
// Simplified and integrated version of std::enable_if_t and
50
54
// std::is_base_of (which are not available on AVR). Integrating them
51
55
// makes things more specific and thus simpler.
56
+ // This type alias resolves to `void` when `Base` is a base class of
57
+ // `Derived`, or fails to resolve otherwise.
52
58
// TODO: This check does not detect private base classes. To do so, a
53
59
// more complicated check is needed, something like
54
60
// https://stackoverflow.com/questions/2910979/how-does-is-base-of-work
@@ -64,6 +70,7 @@ namespace Formatters {
64
70
class DefaultFormatter ;
65
71
}
66
72
73
+ // Forward declaration
67
74
template <typename T>
68
75
Formatters::DefaultFormatter DefaultFormatterFor (T);
69
76
@@ -182,14 +189,15 @@ class Print
182
189
// operator+ to apply each of its arguments to the formatter in
183
190
// turn), but without these the error messages are less clear if
184
191
// incompatible options are mixed (with the below overloads the
185
- // error shows the formatter and the incompatible option, while // without them only the formatter and the entire option list are
192
+ // error shows the formatter and the incompatible option, while
193
+ // without them only the formatter and the entire option list are
186
194
// shown.
187
195
//
188
196
// If we keep these, OptionList::addToFormatter and the related
189
197
// operator+ overload can be removed.
190
198
//
191
199
// If we add one more overload for (Value, OptionList, ...), we can
192
- // also remove the DefaultFormatterForm definition for OptionList.
200
+ // also remove the DefaultFormatterFor definition for OptionList.
193
201
template <
194
202
typename T,
195
203
typename TFormatter,
@@ -459,17 +467,31 @@ auto DefaultFormatterFor(TValue value, OptionList<THead, TTail> list)
459
467
460
468
} // namespace Formatters
461
469
470
+ // The DefaultFormatterFor function is used to define what formatter to
471
+ // use for a value when no formatter is explicitly specified. This is
472
+ // primarily intended to pick a formatter based on the value type (first
473
+ // argument), but it is also possible to look at the value itself when
474
+ // building the formatter. Note that it is not possible to return a
475
+ // different *type* of formatter based on the value, it is possible to
476
+ // set options in the formatter based on the value.
477
+ // TODO: Document ADL stuff?
462
478
template <typename T>
463
- inline Formatters::DefaultFormatter DefaultFormatterFor (T, Formatters::DefaultFormatter::FormatterOption ) {
479
+ inline Formatters::DefaultFormatter DefaultFormatterFor (T) {
464
480
return {};
465
481
}
466
482
483
+ // Overload that decides on a formatter to use based on the value to
484
+ // print as well as the (first) formatter option passed. See
485
+ // `DefaultFormatterFor(T)` overload for more details.
467
486
template <typename T>
468
- inline Formatters::DefaultFormatter DefaultFormatterFor (T) {
487
+ inline Formatters::DefaultFormatter DefaultFormatterFor (T, Formatters::DefaultFormatter::FormatterOption ) {
469
488
return {};
470
489
}
471
490
491
+ // TODO: Fix this in Arduino.h
472
492
#undef HEX
493
+
494
+ // TODO: Finalize options
473
495
inline constexpr Formatters::DefaultFormatter::FormatOptionMinWidth FORMAT_MIN_WIDTH (uint8_t min_width) { return {min_width}; }
474
496
inline constexpr Formatters::DefaultFormatter::FormatOptionBase FORMAT_BASE (uint8_t base) { return {base}; }
475
497
inline constexpr Formatters::DefaultFormatter::FormatOptionPrecision FORMAT_PRECISION (uint8_t prec) { return {prec}; }
@@ -571,7 +593,8 @@ inline size_t Print::print( double n, int prec) { return print(n, FORMAT_
571
593
// live in a namespace). In practice, this means that replacing the
572
594
// default formatter for a native type (without any options) is not
573
595
// possible, since the reference to e.g. DefaultFormatterFor(int) is
574
- // looked up at template definition time, not instantiation time.
596
+ // looked up in the set of overloads that were defined at template
597
+ // definition time, not at instantiation time.
575
598
//
576
599
// Two possible workarounds for this would be to add a wrapper class
577
600
// around values before passing them to DefaultFormatterFor, or adding
@@ -596,6 +619,7 @@ inline size_t Print::print( double n, int prec) { return print(n, FORMAT_
596
619
// SomeOption)", rather than "no such operator
597
620
// operator+(DefaultFormatter, SomeOption)"), so we should probably do
598
621
// that.
622
+ // TODO: This was changed to applyOption, reword
599
623
//
600
624
// Formatters and options are currently passed around as const
601
625
// references, meaning that their printTo methods and addition operators
@@ -623,8 +647,6 @@ inline size_t Print::print( double n, int prec) { return print(n, FORMAT_
623
647
// TODO: Use NoOption dummy argument to DefaultFormatterFor to force
624
648
// ADL?
625
649
//
626
- // TODO: Convert operator+ to applyOption?
627
- //
628
650
// TODO: Naming of option classes (shows up in error message)
629
651
//
630
652
// TODO: Getters and setters for DefaultFormatter options? Helps with
0 commit comments