Browse code

Add implementation

Robert Cranston authored on 18/05/2020 13:08:47
Showing 1 changed files
... ...
@@ -2,10 +2,158 @@
2 2
 
3 3
 A [C++11][] [`std::string`][] [macro][] library.
4 4
 
5
+If [C++20][] is avaiable, [`std::format`][] and [`std::source_location`][] may
6
+be more appropriate. If [C++23][] is available, [`std::stacktrace`][] may be
7
+more appropriate.
8
+
5 9
 [`cxx-str`]: https://git.rcrnstn.net/rcrnstn/cxx-str
6 10
 [C++11]: https://en.wikipedia.org/wiki/C++11
7 11
 [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
8 12
 [macro]: https://en.cppreference.com/w/cpp/preprocessor/replace
13
+[C++20]: https://en.wikipedia.org/wiki/C++20
14
+[`std::format`]: https://en.cppreference.com/w/cpp/utility/format/format
15
+[`std::source_location`]: https://en.cppreference.com/w/cpp/utility/source_location
16
+[C++23]: https://en.wikipedia.org/wiki/C++23
17
+[`std::stacktrace`]: https://en.cppreference.com/w/cpp/utility/basic_stacktrace
18
+
19
+## Usage
20
+
21
+Note that macros can result in unintuitive behavior.
22
+
23
+Looking at the [source][] and [test][] is the best way to understand usage.
24
+
25
+Throughout, arguments are only evaluated once. When [lambda][]s are defined and
26
+immediately called behind the scenes, values are implicitly [capture][]d by
27
+reference. The only lambda that implicitly captures by value is
28
+`STR_FUNC(VALUE)`.
29
+
30
+Include the header:
31
+
32
+```cpp
33
+#include <str.hpp>
34
+```
35
+
36
+There are a few different categories of functionality:
37
+
38
+-   Easy access to [`std::ostringstream`][]'s [`operator<<`][] and [`str()`][].
39
+    The `VALUE` expressions below can contain several values joined with `<<`.
40
+
41
+    `STR(VALUE)` produces a string.
42
+
43
+    `STR_FUNC(VALUE)` produces a [lambda][], which implicitly [capture][]s by
44
+    value, and returns a string. Useful for lazy evaluation of costly string
45
+    operations. For good performance, make sure the standard library can
46
+    perform Small String Optimization ([SSO][]) (and if used with
47
+    [`std::function`][], Small Object Optimization ([SOO][])).
48
+
49
+    `STR_JOIN(JOIN, ITERATOR, VALUE, ...)` makes the variable name `ITERATOR`
50
+    available in the `VALUE` expression, and joins the corresponding non-empty
51
+    (as interpreted by `STR(VALUE)`) elements of `...` with `JOIN`.
52
+
53
+    `STR_JOIN_INIT(JOIN, ITERATOR, VALUE, TYPE, ...)` forwards to
54
+    `STR_JOIN(JOIN, ITERATOR, VALUE, ...)`, passing
55
+    [`std::initializer_list`][]`<TYPE>`[`__VA_ARGS__`][]`)` as the last
56
+    argument. Notice the lack of braces, they have to be supplied manually.
57
+
58
+    `STR_JOIN_INITSTR(JOIN, ITERATOR, VALUE, ...)` forwards to `STR_JOIN_INIT`
59
+    with `std::string` as the `TYPE` argument.
60
+
61
+-   Easy access to the stringifying and concatenating [`#` and `##`
62
+    operators][] to help map constants to strings.
63
+
64
+    `STR_CASE(CASE)` uses `case` and `return` statements: `case (CASE): return
65
+    (#CASE);`.
66
+
67
+    `STR_COND(VALUE, CASE)` uses the [conditional operator][]: `((VALUE) ==
68
+    (CASE)) ? (#CASE) :`.
69
+
70
+    `STR_INIT(CASE)` uses [list initialization][]: `{(CASE), (#CASE)},`.
71
+
72
+    `STR_ARGS(ARG)` expands to `ARG, #ARG`.
73
+
74
+    `STR_ARGS_PREFIX(PREFIX, ARG)` expands to `PREFIX##ARG, #ARG`.
75
+
76
+-   Easy access to source file and line.
77
+
78
+    `STR_HERE(VALUE)` joins [`__FILE__` and `__LINE__`][] and [`__func__`][]
79
+    with `":"`, and appends `": "` and the given argument to produce a string.
80
+
81
+-   Easy handling to ([nested][]) [`std::exception`][]s, which contain strings
82
+    accessible through the [`what()`][] method.
83
+
84
+    `STR_EXCEPTION` can be defined to control what exceptions are thrown by the
85
+    macros below. If it is not defined, [`std::runtime_error`][] is used.
86
+
87
+    `STR_THROW(VALUE)` [`throw`][]s a `STR_EXCEPTION` initialized with
88
+    `STR(VALUE)`.
89
+
90
+    `STR_THROW_ERRNO()` calls `STR_THROW` with the argument
91
+    `std::generic_category().message(errno) << "."`.
92
+
93
+    `STR_RETHROW(VALUE)` calls [`std::terminate`][] if called outside a
94
+    [`catch`][] block. Otherwise, `STR_THROW`s `VALUE` followed by the
95
+    [`what()`][] of the current exception (so it is appropriate to include a
96
+    separator manually) if it is a (derives from) [`std::exception`][],
97
+    otherwise simply rethrows the current exception.
98
+
99
+    `STR_NESTED_THROW(VALUE)` calls [`std::throw_with_nested`][] on a
100
+    `STR_EXCEPTION` initialized with `STR(VALUE)`.
101
+
102
+    `STR_NESTED_THROW_ERRNO()` calls `STR_NESTED_THROW` with the argument
103
+    `std::generic_category().message(errno) << "."`.
104
+
105
+    `STR_NESTED_WHAT(JOIN, EXCEPTION)` joins the strings returned by the
106
+    (optionally) [nested][] [`std::exception`][]-based `EXCEPTION`'s
107
+    [`what()`][] methods with `JOIN`, and returns the resulting string.
108
+
109
+[source]: include/str.hpp
110
+[test]: tests/str.cpp
111
+[lambda]: https://en.cppreference.com/w/cpp/language/lambda
112
+[capture]: https://en.cppreference.com/w/cpp/language/lambda#Lambda_capture
113
+[`std::ostringstream`]: https://en.cppreference.com/w/cpp/io/basic_ostringstream
114
+[`operator<<`]: https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt
115
+[`str()`]: https://en.cppreference.com/w/cpp/io/basic_ostringstream/str
116
+[SSO]: https://en.cppreference.com/w/cpp/language/acronyms
117
+[`std::function`]: https://en.cppreference.com/w/cpp/utility/functional/function
118
+[SOO]: https://en.cppreference.com/w/cpp/language/acronyms
119
+[`std::initializer_list`]: https://en.cppreference.com/w/cpp/utility/initializer_list
120
+[`__VA_ARGS__`]: https://en.cppreference.com/w/cpp/preprocessor/replace
121
+[`#` and `##` operators]: https://en.cppreference.com/w/cpp/preprocessor/replace#.23_and_.23.23_operators
122
+[list initialization]: https://en.cppreference.com/w/cpp/language/list_initialization
123
+[conditional operator]: https://en.cppreference.com/w/cpp/language/operator_other#Conditional_operator
124
+[`__FILE__` and `__LINE__`]: https://en.cppreference.com/w/c/preprocessor/line
125
+[`__func__`]: https://en.cppreference.com/w/cpp/language/function#func
126
+[`#ifndef`]: https://en.cppreference.com/w/cpp/preprocessor/conditional
127
+[`NDEBUG`]: https://en.cppreference.com/w/c/error/assert
128
+[nested]: https://en.cppreference.com/w/cpp/error/nested_exception
129
+[`std::exception`]: https://en.cppreference.com/w/cpp/error/exception
130
+[`what()`]: https://en.cppreference.com/w/cpp/error/exception/what
131
+[`std::runtime_error`]: https://en.cppreference.com/w/cpp/error/runtime_error
132
+[`throw`]: https://en.cppreference.com/w/cpp/language/throw
133
+[`std::terminate`]: https://en.cppreference.com/w/cpp/error/terminate
134
+[`catch`]: https://en.cppreference.com/w/cpp/language/try_catch
135
+[`std::throw_with_nested`]: https://en.cppreference.com/w/cpp/error/throw_with_nested
136
+
137
+## Test output
138
+
139
+The [test][] outputs:
140
+
141
+```
142
+0x3
143
+0x3
144
+"first", "", "third"
145
+first, third
146
+
147
+first
148
+unknown
149
+third
150
+
151
+/path/to/cxx-str/tests/str.cpp:96: Hello from here
152
+
153
+Failed to do outer:
154
+Failed to do inner:
155
+Expected this, got that.
156
+```
9 157
 
10 158
 ## Building
11 159
 
Browse code

Add project

Robert Cranston authored on 23/02/2021 01:12:10
Showing 1 changed files
... ...
@@ -7,6 +7,12 @@ A [C++11][] [`std::string`][] [macro][] library.
7 7
 [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
8 8
 [macro]: https://en.cppreference.com/w/cpp/preprocessor/replace
9 9
 
10
+## Building
11
+
12
+See [`BUILDING.md`][].
13
+
14
+[`BUILDING.md`]: BUILDING.md
15
+
10 16
 ## License
11 17
 
12 18
 Licensed under the [ISC License][] unless otherwise noted, see the
Browse code

Add license

Robert Cranston authored on 18/05/2020 12:55:23
Showing 1 changed files
... ...
@@ -6,3 +6,11 @@ A [C++11][] [`std::string`][] [macro][] library.
6 6
 [C++11]: https://en.wikipedia.org/wiki/C++11
7 7
 [`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
8 8
 [macro]: https://en.cppreference.com/w/cpp/preprocessor/replace
9
+
10
+## License
11
+
12
+Licensed under the [ISC License][] unless otherwise noted, see the
13
+[`LICENSE`][] file.
14
+
15
+[ISC License]: https://choosealicense.com/licenses/isc/
16
+[`LICENSE`]: LICENSE
Browse code

Add readme

Robert Cranston authored on 18/05/2020 12:31:27
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,8 @@
1
+# [`cxx-str`][]
2
+
3
+A [C++11][] [`std::string`][] [macro][] library.
4
+
5
+[`cxx-str`]: https://git.rcrnstn.net/rcrnstn/cxx-str
6
+[C++11]: https://en.wikipedia.org/wiki/C++11
7
+[`std::string`]: https://en.cppreference.com/w/cpp/string/basic_string
8
+[macro]: https://en.cppreference.com/w/cpp/preprocessor/replace