Skip to content

Commit a44b584

Browse files
author
mikee47
committed
Review and update documentation
1 parent b101263 commit a44b584

File tree

9 files changed

+42
-67
lines changed

9 files changed

+42
-67
lines changed

map.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ Structure
102102
The macro in the first example above produces a structure like this::
103103

104104
constexpr const struct {
105-
ObjectBase object;
105+
Map<MapPair<int, String>> object;
106106
MapPair<int, String> data[2];
107107
} __fstr__intmap PROGMEM = {
108108
{16},
109109
{35, &content1},
110110
{180, &content2},
111111
};
112-
const Map<int, String>& intmap = __fstr__intmap.object.as<Map<int, String>>();
112+
const Map<int, String>& intmap PROGMEM = __fstr__intmap.object;
113113

114114
Note: ``FSTR::`` namespace qualifier omitted for clarity.
115115

object.rst

+17-23
Original file line numberDiff line numberDiff line change
@@ -59,30 +59,35 @@ base class, and looks like this (methods omitted)::
5959

6060
``flashLength_`` must not be accessed directly; use the ``length()`` method instead.
6161

62-
Data structures are created like this::
62+
Data structures are created using, for example, ``DEFINE_FSTR(helloData, "hello")``.
63+
This generates the following layout::
6364

6465
constexpr const struct {
65-
ObjectBase object;
66+
FSTR::String object;
6667
char data[8];
67-
} flashHelloData PROGMEM = {
68+
} __fstr__helloData PROGMEM = {
6869
{5},
6970
"hello"
7071
};
72+
const FSTR::String& helloData PROGMEM = __fstr__helloData.object;
7173

72-
The ``object`` field may then be cast to a reference of the required type, like this::
74+
.. note::
7375

74-
auto& str = flashHelloData.object.as<FSTR::String>();
76+
The ``__fstr__`` prefix ensures that these structures are stored in flash memory on the esp8266.
77+
When templates are involved the ``PROGMEM`` segment attribute gets discarded.
7578

76-
If you want to access it as an array, do this::
77-
78-
auto& arr = str.as<FSTR::Array<char>>();
79+
Do not access ``__fstr__helloData`` directly, it may change in future library versions.
7980

8081
References are an efficient and convenient way to access an Object, and should not consume
81-
any memory themselves as the compiler/linker resolve them to the actual object.
82+
any memory themselves as the compiler/linker resolves them to the actual object.
8283

8384
However, in practice the Espressif compiler stores a full pointer to most things to support
8485
relative addressing, and if the references aren't declared PROGMEM they'll consume RAM.
8586

87+
Objects may be cast to a reference of another required type, like this::
88+
89+
auto& arr = helloData.as<FSTR::Array<char>>();
90+
8691

8792
Copy behaviour
8893
--------------
@@ -105,16 +110,7 @@ This means classes cannot have:
105110
- virtual functions
106111
- base classes (until C++17)
107112

108-
This is why :cpp:class:`FSTR::ObjectBase` is used to define data structures.
109-
110-
Classes created using the :cpp:class:`FSTR::Object` template ensures the necessary constructors
111-
are available to do this::
112-
113-
auto myCopy = flashHelloData.object.as<FSTR::String>();
114-
Serial.print("myCopy.length() = ");
115-
Serial.println(myCopy.length());
116-
117-
The macros create an appropriate Object& reference for you.
113+
This is why objects have no constructors or assignment operators.
118114

119115

120116
Structure checks
@@ -129,12 +125,10 @@ You may encounter one of the following errors during compilation:
129125
- FSTR structure not POD
130126

131127
This generally means one or more of the arguments in the initialisation data is not ``constexpr``.
132-
Most compilers are quite relaxed about this but ``GCC 4.8.5`` is particularly thick.
133128

134129
In testing, this happens with references for global Objects, which of course cannot be constexpr.
135-
To fix it, the offending Object either needs to be redefined LOCAL, or if the Object data is in
136-
scope (i.e. defined in the same source file) then you can get a direct pointer to it using
137-
the :c:func:`FSTR_PTR` macro.
130+
To fix it, the offending Object needs to be redefined LOCAL.
131+
138132

139133
Macros
140134
------

src/include/FlashString/Object.hpp

+2-21
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,9 @@
5757
/**
5858
* @brief Given an Object& reference, return a pointer to the actual object
5959
* @param objref
60-
*
61-
* When an Object pointer is required, such when defining entries for a Vector or Map,
62-
* it is usually sufficient to use &objref.
63-
*
64-
* However, some older compilers such as GCC 4.8.5 requires such references to
65-
* be declared constexpr. For example, this fails with `FSTR structure not POD`:
66-
*
67-
* DEFINE_FSTR(globalStringRef, "This creates a global reference");
68-
* DEFINE_VECTOR(myVector, FSTR::String, &globalStringRef);
69-
* ^^^
70-
*
71-
* Global references cannot be declared constexpr, so changing DEFINE_FSTR to DEFINE_FSTR_LOCAL
72-
* will fix the problem.
73-
*
74-
* Another solution is to get a direct pointer to the actual data structure:
75-
*
76-
* DEFINE_VECTOR(myVector, FSTR::String, FSTR_PTR(globalStringRef));
77-
*
78-
* We can only do this of course if the data structure is in scope.
79-
*
60+
* @note This macro was provided for use with old compilers (e.g. GCC 4.8.5) but is no longer required.
8061
*/
81-
#define FSTR_PTR(objref) (&FSTR_DATA_NAME(objref).object)
62+
#define FSTR_PTR(objref) (&objref)
8263

8364
/**
8465
* @brief Check structure is POD-compliant and correctly aligned

string.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,15 @@ This is equivalent to::
9191
Nested Inline Strings
9292
---------------------
9393

94-
It would be really useful to be able to use inline Strings this within nested structures,
94+
It would be really useful to be able to use inline Strings within nested structures,
9595
and this can be done **provided those structures are in RAM**.
9696

9797
.. important:: Inline Strings cannot be used when defining Vectors or Maps.
9898

9999
Here's is a simplified structure we will attempt to initialize::
100100

101101
static const struct {
102-
FlashString* string;
102+
const FlashString* string;
103103
} flashData PROGMEM = { FS_PTR("Inline Flash String") };
104104
Serial.println(*flashData.string);
105105

test/app/custom.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ class CustomTest : public TestGroup
4848
REQUIRE(customObject.description() == F("Object Description "));
4949
REQUIRE(customObject.content().length() == sizeof(data));
5050
REQUIRE(memcmp_P(data, customObject.content().data(), sizeof(data)) == 0);
51+
52+
static const struct {
53+
const FlashString* string;
54+
} flashData = {FS_PTR("Inline Flash String")};
55+
Serial.println(*flashData.string);
5156
}
5257
};
5358

test/app/data.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ DEFINE_FSTR_MAP(stringMap, FSTR::String, FSTR::String, {&key1, &FS_content1}, {&
6464

6565
DEFINE_FSTR_MAP(enumMap, MapKey, FSTR::String, {KeyA, &FS_content1}, {KeyB, &FS_content2});
6666

67-
// Note the use of FSTR_PTR(), required for GCC 4.8.5 because stringVector is a global reference and therefore not constexpr
68-
DEFINE_FSTR_MAP(vectorMap, FSTR::String, FSTR::Vector<FSTR::String>, {&key1, FSTR_PTR(stringVector)});
67+
DEFINE_FSTR_MAP(vectorMap, FSTR::String, FSTR::Vector<FSTR::String>, {&key1, &stringVector});
6968

7069
/**
7170
* Speed

todo.rst

-8
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@ Benchmark filemap
1414
- File access times
1515
- File transfer times
1616

17-
Implement stream operator <<
18-
For simpler printing. This is a large architectural decision as Sming doesn't have any of this,
19-
neither it seems does Arduino although some libraries add support for it.
20-
21-
The advantage over Print/Printable is that support can be added using template functions
22-
without modifying the classes themselves. Formatting statements can be inserted to customise
23-
the output.
24-
2517

2618
Formatted print output
2719
We have separate argument for Array printing, but if we want to customise the text for each item

upgrade.rst

+9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ This library was introduced to Sming in version 4.0.1.
1616
If you are migrating from Sming 3.7.0 or later and have used FlashString in your projects,
1717
some minor changes may be necessary.
1818

19+
Version 2.1
20+
-----------
21+
22+
Support for copied strings was removed to improve portability and performance.
23+
Code simplification allowed use of compilers other than GCC, such as Clang/LLVM.
24+
25+
Code impact is minimal since FlashString objects should be passed by reference or pointer.
26+
27+
1928
FlashString
2029
~~~~~~~~~~~
2130

vector.rst

+4-9
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ Vectors
66
Introduction
77
------------
88

9-
A :cpp:class:`FSTR::Vector` is an array of Object pointers::
10-
11-
struct Vector<ObjectType> {
12-
FSTR::Object object;
13-
ObjectType* entries[];
14-
};
9+
A :cpp:class:`FSTR::Vector` is an array of Object pointers.
1510

1611
A key use for this is the construction of string tables.
1712

@@ -67,8 +62,8 @@ Structure
6762

6863
The above example generates a structure like this::
6964

70-
const struct {
71-
ObjectBase object;
65+
constexpr const struct {
66+
Vector<String*> object;
7267
String* entries[4];
7368
} __fstr__myTable PROGMEM = {
7469
{16},
@@ -77,7 +72,7 @@ The above example generates a structure like this::
7772
nullptr,
7873
&str3,
7974
};
80-
const Vector<String>& myTable PROGMEM = __fstr__myTable.as<Vector<String>>();
75+
const Vector<String>& myTable PROGMEM = __fstr__myTable.object;
8176

8277
Note: ``FSTR::`` namespace qualifier omitted for clarity.
8378

0 commit comments

Comments
 (0)