Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project
adheres to Semantic Versioning.
Added
Changed
General
- Combined the
boba
library with the vm
library, then renamed it to bolt
Deprecated
Removed
Fixed
Security
Released on February 05, 2022.
Added
parsing
library
- A new combinator called
Map
and associated factory function make_map()
- Accepts a parser and a function and transforms the result of the parser using the function
- A new combinator called
Bind
and associated factory function make_bind()
- Uses the result of one parser to build a new parser, then applies the new parser
- A new combinator called
Tee
and associated factory function make_tee()
- Similar to
Bind
, but keeps the output of both parsers and returns it in a std::pair
- Several new factory functions and types in the
bytes
namespace (used to be the bits
namespace):
Endianness
, an enumeration used to distinguish big-endian and little-endian parsers from one another
U8Le
, U16Le
, U32Le
, U64Be
, U8Be
, U16Be
, U32Be
, and U64Be
: parsers for the appropriate type and endianness
make_exact()
and make_take()
: factory functions for creating Exact
and Take
parsers
make_u8_le()
, make_u16_le()
, make_u32_le()
, make_u64_le()
: factory functions for little-endian unsigned integer parsers
make_u8_be()
, make_u16_be()
, make_u32_be()
, make_u64_be()
: factory functions for big-endian unsigned integer parsers
Changed
Build system
- Disabled the
C4180
compiler warning on MSVC due to not being helpful and causing the build to fail
bobadump
executable
- Updated output to correspond with new Boba format
boba
library
- Total overhaul of the file format and internals
- The schema block is gone; instead we have a special container metadata section
- The
from_bytes()
API is exactly the same, but the Container
type is now a simple record containing a vector of headers
- New namespace:
container
- Contains simple record types for both individual block headers and the container as a whole
- New namespace:
read
- The
from_bytes()
function was moved here
parsing
library
- The meaning of the
Into
parser combinator has changed
Into<T>
now converts the result of its wrapped parser into a T
using one of T
's constructors
- The
bits
namespace has been renamed to bytes
, and also renamed the contents:
- Renamed
BitsState
type to State
- Renamed
ByteSequence
parser to Exact
- Renamed
SizedByteSequence
parser to Take
- Combined
BigEndianUnsignedInteger
and LittleEndianUnsignedInteger
parsers into UnsignedInteger
Removed
boba
library
- The
metadata
namespace is gone; see the new container
and read
namespaces for equivalent functionality
parsing
library
- The
>>
operator is no longer overloaded to construct an instance of Into
Fixed
bobadump
executable
- Tests were not passing on windows due to
\r\n
line endings not being handled correctly in the test script
parsing
library
- Compilation errors on macOS due to mis-ordered class fields and missing constructors
Released on January 01, 2022.
Added
bobadump
executable
- New executable for dumping Boba files
- No options; just use
crucible-bobadump BOBA_FILE
- Prints the schema header (but not the schema entries) and each user header
core
library
- New formatter for primitive integer types called
format_integral()
- Will work on anything for which
std::is_integral
evaluates to true
- New abstract method in
AbstractError
called describe()
- In contrast to
format()
, which is intended for developers, describe()
is intended for end users
either::Either
got new methods bind_lhs()
and bind_rhs()
- Maps a value to a whole new
Either
instance
- This is in contrast to
map_lhs()
and map_rhs()
, which map a value to another value
- Can be used to chain
Either
-returning functions together
os
library
- New library for abstracting over "operating-system-y" things
- Automatically switches between
unix
and windows
as a backend depending on the compilation target
- The
fs
namespace has platform-agnostic wrapper functions for all of the utilities in unix::fs
and windows::fs
Build system
- Support for Python test drivers via
add_crucible_python_test()
(intended mainly for testing executables)
General
- Added information about Python tests to the readme
- Added information about supported compilation targets to the readme
Changed
bobadump
executable
- Renamed from
boba-dump
to just bobadump
core
library
either::LHS
and either::RHS
renamed to either::Lhs
and either::Rhs
for readability
os
library
- The Windows implementation of the
fs
namespace now uses the bind_lhs()
and bind_rhs()
APIs of core::either::Either
Build system
- Silenced the message from
find_package
, which could be really long and was basically just noise
General
- All uses of
Result
have been changed to Either
to remove duplicated code
- Better end-user error messages across the board
- Uses of "Boba" as a word standardized on camel-case, not uppercase (
BOBA
) or lowercase (boba
)
Removed
- The
core::result
namespace has been completely removed; use core::either
instead
Fixed
parsing
library
- Compilation error on MSVC due to signed/unsigned comparison mismatch
unix
library
- Errors now have their details reported properly (we see the
errno
message)
windows
library
- Errors now have their details reported properly (we see the
GetLastError()
message)
Released on December 04, 2021.
Added
New libraries
boba
, the reference implementation of the BOBA (Bunch Of Big Arrays) file format
boba
library
- The new
errors
namespace:
- The main error class
BobaError
- The
ParsingFailed
error variant for when loading a BOBA container fails
- A type alias
BobaResult
for core::result::Result
- The new
metadata
namespace:
- A POD type called
Header
for keeping the (almost) raw information about each block header
- A type called
Schema
that wraps the very first Header
of a container, providing information about the rest of the contents
- A type called
Container
that holds all block headers and provides iterator access to them, as well as the schema
- A function called
from_bytes()
which deserializes a byte stream into a Container
core
library
- The
format
namespace:
- Lots of functions for formatting anything you can think of: STL containers, plain arrays, C strings, pointers...
- A
format_anything()
function which intelligently selects a formatter based on a compile-time type check
- Lots of new
ASSERT
macros, for parity with the EXPECT
API
- The
errors
namespace:
- An abstract base class called
AbstractError
, intended to be used for the Failure
alternative of Result
instances
- Support for
std::tuple
in format::format_anything()
constexpr
comparison operators for none::None
parsing
library
- A new combinator called
SequenceOf
- Used to parse an exact number of repetitions of a single structure
- Fails if there aren't enough occurrences (but it's fine to have more)
- Has an associated error called
SequenceOfError
- The
errors
namespace:
- Error variants
AmbiguousMatch
, UnexpectedInput
, and UnexpectedEndOfInput
- The main error class
ParsingError
and a Result
alias named ParsingResult
- A new combinator called
Tuple
- Used to parse a heterogeneous sequence of substructures
- No combinator operator; use
combinators::make_tuple()
- New factory functions for each combinator:
make_one_of()
, make_pair()
, make_into()
, and make_sequence_of()
unix
library
- The
errors
namespace:
- The
HostError
type, which is moved from the old errno_error::ErrnoError
type
- Error variants moved from the
fs
namespace
- The main error class
UnixError
and a Result
alias named UnixError
windows
library
- The
errors
namespace:
- The
HostError
, which is moved from the old windows_error::WindowsError
type
- Error variants moved from the
fs
and transcoding
namespaces
- The main error class
WindowsError
and a Result
alias named WindowsResult
testing
library
- Self tests (at least, for the parts that can be isolated and tested!)
Changed
ASSERT
, EXPECT
, and Result
now use the format_anything()
function to render objects
- All error handling is now done using a combination of
core::errors::AbstractError
and core::result::Result
- Each library now has an
errors
namespace in which it defines its own specializations of these types
core
library
none::None
now formats as "None"
instead of "None {}"
parsing
library
AndThen
combinator renamed to Pair
(as a special case of Tuple
)
Removed
ASSERT_NOT_NULL
is gone; use ASSERT_NE(thing, nullptr)
- The
parsing::result
, unix::errno_error
, and windows::windows_error
namespaces are all gone
- See the
errors
namespaces in each library for a standardized replacement
Released on November 06, 2021.
Added
core
library
- A new namespace called
assert
, containing functions for implementing the ASSERT
macro family
- In the
assert
namespace:
- A pair of new macros called
ASSERT
and ASSERT_NOT_NULL
, which terminate the program with a message if the assertion does not pass
- A template function called
fail
, which implements the assertion failure mechanism
- A new namespace called
either
, containing the Either
type for holding one of two types of value
- In the
either
namespace:
- A tag type called
PreventSelectionForCopyAndMove
used internally
- A pair of templates called
LHS
and RHS
which distinguish the alternatives of an Either
- A template called
Either
which can hold one of two values, which can have different types
- A pair of functions called
make_lhs()
and make_rhs()
, which can be used to create LHS
and RHS
instances to pass to an Either
parsing
library
- In the
bits
namespace:
- A new parser called
SizedByteSequence
which extracts a specific number of bytes from the input
- In the
combinators
namespace:
- A new combinator called
Into
, which functions like AndThen
but dynamically constructs the second parser based on the result of the first parser
- Two new errors called
AndThenError
and IntoError
, which serve as error types for the AndThen
and Into
combinators
- In the
combinators::operators
namespace:
- An overloaded
>>
operator, which builds Into
instances from a parser and a function
testing
library
- In the
expect
namespace:
- A pair of new macros called
EXPECT_CONTAINER_EQ
and EXPECT_CONTAINER_NE
, which check for (in)equality between two iterables
- In the
abstract_reporter
namespace:
- The
AbstractReporter
class now has default do-nothing implementations for all of its virtual methods
- Two new hook methods for
AbstractReporter
: handle_group_start()
and handle_group_end()
, which get the name of the group
- In the
reporter
namespace:
- Forwarding methods for the
handle_group_start()
and handle_group_end()
hooks
- In the
console_reporter
namespace:
- An implementation of
handle_group_start
that prints the group name
Changed
testing
library
- Scenarios and fixtures now both accept a tag argument before the name, which groups the fixtures and scenarios together
- Tags can be filtered on the command line with the
-t
or --tag
option
- Fixtures will only be run for the scenarios that have the same tag
BeforeAll
and AfterAll
fixtures will only run if their tag isn't being filtered out
- Output rendering is much clearer
- A count of total scenarios run is now printed
- Fixtures are now printed at the same level as scenarios instead of inside them
- Fixtures receive a pass/fail note (when they would be printed anyways)
- Added icons for each keyword to make distinguishing them a little clearer
- Removed all white and bright white to make reading output on a white background easier
- "Tags" renamed to "Groups"
- The option in the CLI runner has been changed from
-t/--tag
to -g/--group
- Groups are now used as "containers" for scenarios
- There are now two loops: one over each group, and another over each scenario within the group
BeforeAll
and AfterAll
fixtures now run only within their group, not at the start or end of the whole suite
- The console reporter will show groups as the main heading now, with scenarios and fixtures underneath
unix
library
test_fs
now uses the fixture mechanism to create and delete its file structure
General
- Turned all instances of
std::u8string
, std::u8string_view
, char8_t
, and u8""
literals back into their legacy versions due to bad support
- Standardized constructor syntax (
{}
unless ()
is semantically required)
parsing
library
- The
bits::ByteSequence
and text::CharacterSequence
parsers now make a deep copy of their sequences
- The
bits::ByteSequence
parser has been renamed to bits::ExactByteSequence
Fixed
- Compilation error on AppleClang:
no viable constructor or deduction guide
in core::assert::fail()
Released on October 02, 2021.
Added
New libraries
vm
library for the virtual machine implementation
parsing
library for parser combinators
parsing
library features
bits
namespace containing primitives for parsing binary data
FixedWidthUnsignedIntegerType
concept, which constrains to one of the std::uintN_t
types
ByteSequenceMismatch
basic error type
UnexpectedEndOfInput
basic error type
BitsError
composite error type
BitsState
type specialized for binary data
ByteSequence
parser which matches an exact sequence of bytes
LittleEndianUnsignedInteger
parser template
BigEndianUnsignedInteger
parser template
combinators
namespace containing types for combining simple parsers into more complex parsers
BothMatch
error template
NeitherMatch
error template
OneOfError
composite error type
OneOf
parser combinator, which matches exclusively one or the other of the child parsers
AndThen
parser combinator, which matches one parser followed by another parser and returns both results
operators
namespace containing tools for building combinator trees
operator^
, which combines two parsers using the OneOf
combinator
operator&
, which combines two parsers using the AndThen
combinator
result
namespace containing utility types for the outcomes of individual parsers
Reject
template for holding information about a rejected parse
Accept
template for holding information about an accepted parse
reject
function for building a Reject
wrapped in a core::result::Failure
accept
function for building an Accept
wrapped in a core::result::Success
text
namespace containing primitives for parsing UTF-8 data
CharacterSequenceMismatch
basic error type
TextError
composite error type
TextState
type specialized for UTF-8 data
CharacterSequence
parser which matches an exact sequence of characters
testing
library features
- New namespace:
fixture
for types related to test fixtures
- In the
fixture
namespace:
FixtureFunction
alias for the type of a fixture function
FixtureVariant
template type which serves as a base class for each kind of fixture
BeforeAll
, AfterAll
, BeforeEach
, and AfterEach
tag types which differentiate each kind of fixture
- The
Fixture
type itself, which abstracts over all of these details
- In the
FixtureVariant
type:
- A constructor accepting a
FixtureFunction
- A getter method called
get_name()
which returns the name of the fixture variant based on which derived class calls it
- A method named
execute()
which runs the fixture and returns an outcome, just like a scenario
- In the
BeforeAll
, AfterAll
, BeforeEach
, and AfterEach
types:
- A constant string field containing the name of the variant for reporting purposes
- In the
Fixture
type:
- A constructor which accepts a name and a fixture variant
- A template method called
has_variant()
which checks what kind of fixture this is
- A method called
get_variant_name()
which forwards to get_name()
on the underlying variant
- A getter method called
get_name()
which retrieves the fixture's name
- A method called
execute()
which forwards to execute()
on the underlying variant
- In the
suite
namespace:
- Four new macros which define fixtures in the same way as scenarios:
BEFORE_ALL
, AFTER_ALL
, BEFORE_EACH
, and AFTER_EACH
- A new type called
FixtureRegistrar
which is used by the new macros to add fixtures to the suite
- In the
FixtureRegistrar
type:
- A constructor that forwards to
add_fixture()
on the suite
- In the
Suite
singleton:
- A method called
add_fixture()
which registers a new fixture in the suite
- In
reporter::Reporter
, abstract_reporter::AbstractReporter
, and console_reporter::ConsoleReporter
:
- Two new methods called
handle_fixture_start()
and handle_fixture_end()
which are called before and after each fixture
- Another new method called
set_show_fixtures()
which toggles how much information is reported about fixtures
- In the
expect
namespace:
- A new template function called
fail_comparison()
, which is exactly like fail()
but formats its output specifically as a comparison failure
Changed
Build system
- Upgrade the C++ version to C++20
- Renamed the
test
library to testing
to better fit with other library names (specifically parsing
)
testing
library features
- Print a special message when there are no tests in a test suite
- Tests can now accept a
--show-fixtures
argument on the command line which causes the reporter to print more information about which fixtures run and when
- The
SCENARIO
macro and ScenarioRegistrar
type have been moved to the suite
namespace
- The console reporter will now display a count of total fixture invocations in the suite summary
- All reporters now require a third argument,
fixture_count
, to the handle_suite_end()
method
- The
EXPECT
family of macros now print much more detailed information when a test fails
- In the
expect
namespace:
- The
fail
function now takes more arguments and has been made into a template based on the type of value being EXPECT
ed
Fixed
parsing
library
- Compilation
cast truncates constant value
warning on MSVC
testing
library
- Disallow copying and moving the Suite singleton
- Incorrect include guard symbols
- Compilation warning on AppleClang:
[[nodiscard]]
on a function returning void
Build system
- Give a nice message from CMake instead of weird errors when trying to build for non-64-bit systems
Released on September 04, 2021.
Added
New libraries
core
library for fundamental types and functions used by everything else
test
library for testing infrastructure
unix
library for wrapping Unix-like APIs
windows
library for wrapping Windows APIs
core
library features
core::constant_error
namespace, containing a ConstantError
template for errors with a constant message
core::error_chain
namespace, containing the ErrorChain
class for building complex error types
core::none
namespace, containing the None
type to use as a placeholder
core::resource_warden
namespace, containing a class template for cleaning up raw resources on scope exit
core::result
namespace, containing facilities for operations that can fail
test
library features
test::abstract_reporter
namespace, containing the AbstractReporter
interface
test::cli
namespace, containing a function execute()
that can be called from main()
test::console_reporter
namespace, containing a reporter that writes to stdout
test::expect
namespace, containing macros to express test assertions
test::outcome
namespace, containing types representing scenario outcomes
test::reporter
namespace, containing factories for specific reporters and also a wrapper type
test::scenario
namespace, containing the Scenario
type for representing a single test scenario
test::suite
namespace, containing the Suite
singleton used to hold all of the tests in a suite
unix
library features
unix::errno_error
namespace, containing utilities for working with errno
unix::fs
namespace, containing wrappers for filesystem APIs on Unix-like systems
windows
library features
windows::fs
namespace, containing wrappers for filesystem APIs on Windows
windows::transcoding
namespace, containing functions for transcoding UTF8 with UTF16 for Windows APIs
windows::windows_error
namespace, containing functions and a type for reading and formatting Windows errors
Build system features
AddCrucibleExecutable
module, which provides a wrapper for add_executable()
AddCrucibleLibrary
module, which provides a wrapper for add_library()
AddCrucibleTest
module, which provides a wrapper for add_test()
EnableCompilerWarnings
module, which provides a function that enables common compiler warning flags
EnableRuntimeSanitizers
module, which provides a function that enables ASAN, TSAN, and UBSAN based on options
- Write all final build outputs (executables and libraries) to
${PROJECT_BINARY_DIR}/artifacts
- Automatically export all symbols from all libraries when building Windows DLLs
Repository features
- Build dependencies in the README
- Build instructions in the README
- Test instructions in the README
- Attribution in the README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Changed
#### General
* Combined the `boba` library with the `vm` library, then renamed it to `bolt`
### Deprecated
### Removed
### Fixed
### Security
## [0.6.0]
Released on February 05, 2022.
### Added
#### `parsing` library
* A new combinator called `Map` and associated factory function `make_map()`
* Accepts a parser and a function and transforms the result of the parser using the function
* A new combinator called `Bind` and associated factory function `make_bind()`
* Uses the result of one parser to build a new parser, then applies the new parser
* A new combinator called `Tee` and associated factory function `make_tee()`
* Similar to `Bind`, but keeps the output of both parsers and returns it in a `std::pair`
* Several new factory functions and types in the `bytes` namespace (used to be the `bits` namespace):
* `Endianness`, an enumeration used to distinguish big-endian and little-endian parsers from one another
* `U8Le`, `U16Le`, `U32Le`, `U64Be`, `U8Be`, `U16Be`, `U32Be`, and `U64Be`: parsers for the appropriate type and endianness
* `make_exact()` and `make_take()`: factory functions for creating `Exact` and `Take` parsers
* `make_u8_le()`, `make_u16_le()`, `make_u32_le()`, `make_u64_le()`: factory functions for little-endian unsigned integer parsers
* `make_u8_be()`, `make_u16_be()`, `make_u32_be()`, `make_u64_be()`: factory functions for big-endian unsigned integer parsers
### Changed
#### Build system
* Disabled the [`C4180`] compiler warning on MSVC due to not being helpful and causing the build to fail
#### `bobadump` executable
* Updated output to correspond with new Boba format
#### `boba` library
* Total overhaul of the file format and internals
* The schema block is gone; instead we have a special container metadata section
* The `from_bytes()` API is exactly the same, but the `Container` type is now a simple record containing a vector of headers
* New namespace: `container`
* Contains simple record types for both individual block headers and the container as a whole
* New namespace: `read`
* The `from_bytes()` function was moved here
#### `parsing` library
* The meaning of the `Into` parser combinator has changed
* `Into<T>` now converts the result of its wrapped parser into a `T` using one of `T`'s constructors
* The `bits` namespace has been renamed to `bytes`, and also renamed the contents:
* Renamed `BitsState` type to `State`
* Renamed `ByteSequence` parser to `Exact`
* Renamed `SizedByteSequence` parser to `Take`
* Combined `BigEndianUnsignedInteger` and `LittleEndianUnsignedInteger` parsers into `UnsignedInteger`
### Removed
#### `boba` library
* The `metadata` namespace is gone; see the new `container` and `read` namespaces for equivalent functionality
#### `parsing` library
* The `>>` operator is no longer overloaded to construct an instance of `Into`
* Use `make_into()` instead
### Fixed
#### `bobadump` executable
* Tests were not passing on windows due to `\r\n` line endings not being handled correctly in the test script
#### `parsing` library
* Compilation errors on macOS due to mis-ordered class fields and missing constructors
## [0.5.0]
Released on January 01, 2022.
### Added
#### `bobadump` executable
* New executable for dumping Boba files
* No options; just use `crucible-bobadump BOBA_FILE`
* Prints the schema header (but not the schema entries) and each user header
#### `core` library
* New formatter for primitive integer types called `format_integral()`
* Will work on anything for which `std::is_integral` evaluates to `true`
* New abstract method in `AbstractError` called `describe()`
* In contrast to `format()`, which is intended for developers, `describe()` is intended for end users
* `either::Either` got new methods `bind_lhs()` and `bind_rhs()`
* Maps a value to a whole new `Either` instance
* This is in contrast to `map_lhs()` and `map_rhs()`, which map a value to another value
* Can be used to chain `Either`-returning functions together
#### `os` library
* New library for abstracting over "operating-system-y" things
* Automatically switches between `unix` and `windows` as a backend depending on the compilation target
* The `fs` namespace has platform-agnostic wrapper functions for all of the utilities in `unix::fs` and `windows::fs`
#### Build system
* Support for Python test drivers via `add_crucible_python_test()` (intended mainly for testing executables)
#### General
* Added information about Python tests to the readme
* Added information about supported compilation targets to the readme
### Changed
#### `bobadump` executable
* Renamed from `boba-dump` to just `bobadump`
#### `core` library
* `either::LHS` and `either::RHS` renamed to `either::Lhs` and `either::Rhs` for readability
#### `os` library
* The Windows implementation of the `fs` namespace now uses the `bind_lhs()` and `bind_rhs()` APIs of `core::either::Either`
#### Build system
* Silenced the message from `find_package`, which could be really long and was basically just noise
#### General
* All uses of `Result` have been changed to `Either` to remove duplicated code
* Better end-user error messages across the board
* Uses of "Boba" as a word standardized on camel-case, not uppercase (`BOBA`) or lowercase (`boba`)
### Removed
* The `core::result` namespace has been completely removed; use `core::either` instead
### Fixed
#### `parsing` library
* Compilation error on MSVC due to signed/unsigned comparison mismatch
#### `unix` library
* Errors now have their details reported properly (we see the `errno` message)
#### `windows` library
* Errors now have their details reported properly (we see the `GetLastError()` message)
## [0.4.0]
Released on December 04, 2021.
### Added
#### New libraries
* `boba`, the reference implementation of the BOBA (Bunch Of Big Arrays) file format
#### `boba` library
* The new `errors` namespace:
* The main error class `BobaError`
* The `ParsingFailed` error variant for when loading a BOBA container fails
* A type alias `BobaResult` for `core::result::Result`
* The new `metadata` namespace:
* A POD type called `Header` for keeping the (almost) raw information about each block header
* A type called `Schema` that wraps the very first `Header` of a container, providing information about the rest of the contents
* A type called `Container` that holds all block headers and provides iterator access to them, as well as the schema
* A function called `from_bytes()` which deserializes a byte stream into a `Container`
#### `core` library
* The `format` namespace:
* Lots of functions for formatting anything you can think of: STL containers, plain arrays, C strings, pointers...
* A `format_anything()` function which intelligently selects a formatter based on a compile-time type check
* Lots of new `ASSERT` macros, for parity with the `EXPECT` API
* The `errors` namespace:
* An abstract base class called `AbstractError`, intended to be used for the `Failure` alternative of `Result` instances
* Support for `std::tuple` in `format::format_anything()`
* `constexpr` comparison operators for `none::None`
#### `parsing` library
* A new combinator called `SequenceOf`
* Used to parse an exact number of repetitions of a single structure
* Fails if there aren't enough occurrences (but it's fine to have more)
* Has an associated error called `SequenceOfError`
* The `errors` namespace:
* Error variants `AmbiguousMatch`, `UnexpectedInput`, and `UnexpectedEndOfInput`
* The main error class `ParsingError` and a `Result` alias named `ParsingResult`
* A new combinator called `Tuple`
* Used to parse a heterogeneous sequence of substructures
* No combinator operator; use `combinators::make_tuple()`
* New factory functions for each combinator: `make_one_of()`, `make_pair()`, `make_into()`, and `make_sequence_of()`
#### `unix` library
* The `errors` namespace:
* The `HostError` type, which is moved from the old `errno_error::ErrnoError` type
* Error variants moved from the `fs` namespace
* The main error class `UnixError` and a `Result` alias named `UnixError`
#### `windows` library
* The `errors` namespace:
* The `HostError`, which is moved from the old `windows_error::WindowsError` type
* Error variants moved from the `fs` and `transcoding` namespaces
* The main error class `WindowsError` and a `Result` alias named `WindowsResult`
#### `testing` library
* Self tests (at least, for the parts that can be isolated and tested!)
### Changed
* `ASSERT`, `EXPECT`, and `Result` now use the `format_anything()` function to render objects
* All error handling is now done using a combination of `core::errors::AbstractError` and `core::result::Result`
* Each library now has an `errors` namespace in which it defines its own specializations of these types
#### `core` library
* `none::None` now formats as `"None"` instead of `"None {}"`
#### `parsing` library
* `AndThen` combinator renamed to `Pair` (as a special case of `Tuple`)
### Removed
* `ASSERT_NOT_NULL` is gone; use `ASSERT_NE(thing, nullptr)`
* The `parsing::result`, `unix::errno_error`, and `windows::windows_error` namespaces are all gone
* See the `errors` namespaces in each library for a standardized replacement
## [0.3.0]
Released on November 06, 2021.
### Added
#### `core` library
* A new namespace called `assert`, containing functions for implementing the `ASSERT` macro family
* In the `assert` namespace:
* A pair of new macros called `ASSERT` and `ASSERT_NOT_NULL`, which terminate the program with a message if the assertion does not pass
* A template function called `fail`, which implements the assertion failure mechanism
* A new namespace called `either`, containing the `Either` type for holding one of two types of value
* In the `either` namespace:
* A tag type called `PreventSelectionForCopyAndMove` used internally
* A pair of templates called `LHS` and `RHS` which distinguish the alternatives of an `Either`
* A template called `Either` which can hold one of two values, which can have different types
* A pair of functions called `make_lhs()` and `make_rhs()`, which can be used to create `LHS` and `RHS` instances to pass to an `Either`
#### `parsing` library
* In the `bits` namespace:
* A new parser called `SizedByteSequence` which extracts a specific number of bytes from the input
* In the `combinators` namespace:
* A new combinator called `Into`, which functions like `AndThen` but dynamically constructs the second parser based on the result of the first parser
* Two new errors called `AndThenError` and `IntoError`, which serve as error types for the `AndThen` and `Into` combinators
* In the `combinators::operators` namespace:
* An overloaded `>>` operator, which builds `Into` instances from a parser and a function
#### `testing` library
* In the `expect` namespace:
* A pair of new macros called `EXPECT_CONTAINER_EQ` and `EXPECT_CONTAINER_NE`, which check for (in)equality between two iterables
* In the `abstract_reporter` namespace:
* The `AbstractReporter` class now has default do-nothing implementations for all of its virtual methods
* Two new hook methods for `AbstractReporter`: `handle_group_start()` and `handle_group_end()`, which get the name of the group
* In the `reporter` namespace:
* Forwarding methods for the `handle_group_start()` and `handle_group_end()` hooks
* In the `console_reporter` namespace:
* An implementation of `handle_group_start` that prints the group name
### Changed
#### `testing` library
* Scenarios and fixtures now both accept a tag argument before the name, which groups the fixtures and scenarios together
* Tags can be filtered on the command line with the `-t` or `--tag` option
* Fixtures will only be run for the scenarios that have the same tag
* `BeforeAll` and `AfterAll` fixtures will only run if their tag isn't being filtered out
* Output rendering is much clearer
* A count of total scenarios run is now printed
* Fixtures are now printed at the same level as scenarios instead of inside them
* Fixtures receive a pass/fail note (when they would be printed anyways)
* Added icons for each keyword to make distinguishing them a little clearer
* Removed all white and bright white to make reading output on a white background easier
* "Tags" renamed to "Groups"
* The option in the CLI runner has been changed from `-t/--tag` to `-g/--group`
* Groups are now used as "containers" for scenarios
* There are now two loops: one over each group, and another over each scenario within the group
* `BeforeAll` and `AfterAll` fixtures now run only within their group, not at the start or end of the whole suite
* The console reporter will show groups as the main heading now, with scenarios and fixtures underneath
#### `unix` library
* `test_fs` now uses the fixture mechanism to create and delete its file structure
#### General
* Turned all instances of `std::u8string`, `std::u8string_view`, `char8_t`, and `u8""` literals back into their legacy versions due to bad support
* Standardized constructor syntax (`{}` unless `()` is semantically required)
#### `parsing` library
* The `bits::ByteSequence` and `text::CharacterSequence` parsers now make a deep copy of their sequences
* The `bits::ByteSequence` parser has been renamed to `bits::ExactByteSequence`
### Fixed
* Compilation error on AppleClang: `no viable constructor or deduction guide` in `core::assert::fail()`
## [0.2.0]
Released on October 02, 2021.
### Added
#### New libraries
* `vm` library for the virtual machine implementation
* `parsing` library for parser combinators
#### `parsing` library features
* `bits` namespace containing primitives for parsing binary data
* `FixedWidthUnsignedIntegerType` concept, which constrains to one of the `std::uintN_t` types
* `ByteSequenceMismatch` basic error type
* `UnexpectedEndOfInput` basic error type
* `BitsError` composite error type
* `BitsState` type specialized for binary data
* `ByteSequence` parser which matches an exact sequence of bytes
* `LittleEndianUnsignedInteger` parser template
* `BigEndianUnsignedInteger` parser template
* `combinators` namespace containing types for combining simple parsers into more complex parsers
* `BothMatch` error template
* `NeitherMatch` error template
* `OneOfError` composite error type
* `OneOf` parser combinator, which matches exclusively one or the other of the child parsers
* `AndThen` parser combinator, which matches one parser followed by another parser and returns both results
* `operators` namespace containing tools for building combinator trees
* `operator^`, which combines two parsers using the `OneOf` combinator
* `operator&`, which combines two parsers using the `AndThen` combinator
* `result` namespace containing utility types for the outcomes of individual parsers
* `Reject` template for holding information about a rejected parse
* `Accept` template for holding information about an accepted parse
* `reject` function for building a `Reject` wrapped in a `core::result::Failure`
* `accept` function for building an `Accept` wrapped in a `core::result::Success`
* `text` namespace containing primitives for parsing UTF-8 data
* `CharacterSequenceMismatch` basic error type
* `TextError` composite error type
* `TextState` type specialized for UTF-8 data
* `CharacterSequence` parser which matches an exact sequence of characters
#### `testing` library features
* New namespace: `fixture` for types related to test fixtures
* In the `fixture` namespace:
* `FixtureFunction` alias for the type of a fixture function
* `FixtureVariant` template type which serves as a base class for each kind of fixture
* `BeforeAll`, `AfterAll`, `BeforeEach`, and `AfterEach` tag types which differentiate each kind of fixture
* The `Fixture` type itself, which abstracts over all of these details
* In the `FixtureVariant` type:
* A constructor accepting a `FixtureFunction`
* A getter method called `get_name()` which returns the name of the fixture variant based on which derived class calls it
* A method named `execute()` which runs the fixture and returns an outcome, just like a scenario
* In the `BeforeAll`, `AfterAll`, `BeforeEach`, and `AfterEach` types:
* A constant string field containing the name of the variant for reporting purposes
* In the `Fixture` type:
* A constructor which accepts a name and a fixture variant
* A template method called `has_variant()` which checks what kind of fixture this is
* A method called `get_variant_name()` which forwards to `get_name()` on the underlying variant
* A getter method called `get_name()` which retrieves the fixture's name
* A method called `execute()` which forwards to `execute()` on the underlying variant
* In the `suite` namespace:
* Four new macros which define fixtures in the same way as scenarios: `BEFORE_ALL`, `AFTER_ALL`, `BEFORE_EACH`, and `AFTER_EACH`
* A new type called `FixtureRegistrar` which is used by the new macros to add fixtures to the suite
* In the `FixtureRegistrar` type:
* A constructor that forwards to `add_fixture()` on the suite
* In the `Suite` singleton:
* A method called `add_fixture()` which registers a new fixture in the suite
* In `reporter::Reporter`, `abstract_reporter::AbstractReporter`, and `console_reporter::ConsoleReporter`:
* Two new methods called `handle_fixture_start()` and `handle_fixture_end()` which are called before and after each fixture
* Another new method called `set_show_fixtures()` which toggles how much information is reported about fixtures
* In the `expect` namespace:
* A new template function called `fail_comparison()`, which is exactly like `fail()` but formats its output specifically as a comparison failure
### Changed
#### Build system
* Upgrade the C++ version to C++20
* Renamed the `test` library to `testing` to better fit with other library names (specifically `parsing`)
#### `testing` library features
* Print a special message when there are no tests in a test suite
* Tests can now accept a `--show-fixtures` argument on the command line which causes the reporter to print more information about which fixtures run and when
* The `SCENARIO` macro and `ScenarioRegistrar` type have been moved to the `suite` namespace
* The console reporter will now display a count of total fixture invocations in the suite summary
* All reporters now require a third argument, `fixture_count`, to the `handle_suite_end()` method
* The `EXPECT` family of macros now print much more detailed information when a test fails
* In the `expect` namespace:
* The `fail` function now takes more arguments and has been made into a template based on the type of value being `EXPECT`ed
### Fixed
#### `parsing` library
* Compilation `cast truncates constant value` warning on MSVC
#### `testing` library
* Disallow copying and moving the Suite singleton
* Incorrect include guard symbols
* Compilation warning on AppleClang: `[[nodiscard]]` on a function returning `void`
#### Build system
* Give a nice message from CMake instead of weird errors when trying to build for non-64-bit systems
## [0.1.0]
Released on September 04, 2021.
### Added
#### New libraries
* `core` library for fundamental types and functions used by everything else
* `test` library for testing infrastructure
* `unix` library for wrapping Unix-like APIs
* `windows` library for wrapping Windows APIs
#### `core` library features
* `core::constant_error` namespace, containing a `ConstantError` template for errors with a constant message
* `core::error_chain` namespace, containing the `ErrorChain` class for building complex error types
* `core::none` namespace, containing the `None` type to use as a placeholder
* `core::resource_warden` namespace, containing a class template for cleaning up raw resources on scope exit
* `core::result` namespace, containing facilities for operations that can fail
#### `test` library features
* `test::abstract_reporter` namespace, containing the `AbstractReporter` interface
* `test::cli` namespace, containing a function `execute()` that can be called from `main()`
* `test::console_reporter` namespace, containing a reporter that writes to stdout
* `test::expect` namespace, containing macros to express test assertions
* `test::outcome` namespace, containing types representing scenario outcomes
* `test::reporter` namespace, containing factories for specific reporters and also a wrapper type
* `test::scenario` namespace, containing the `Scenario` type for representing a single test scenario
* `test::suite` namespace, containing the `Suite` singleton used to hold all of the tests in a suite
#### `unix` library features
* `unix::errno_error` namespace, containing utilities for working with `errno`
* `unix::fs` namespace, containing wrappers for filesystem APIs on Unix-like systems
#### `windows` library features
* `windows::fs` namespace, containing wrappers for filesystem APIs on Windows
* `windows::transcoding` namespace, containing functions for transcoding UTF8 with UTF16 for Windows APIs
* `windows::windows_error` namespace, containing functions and a type for reading and formatting Windows errors
#### Build system features
* `AddCrucibleExecutable` module, which provides a wrapper for `add_executable()`
* `AddCrucibleLibrary` module, which provides a wrapper for `add_library()`
* `AddCrucibleTest` module, which provides a wrapper for `add_test()`
* `EnableCompilerWarnings` module, which provides a function that enables common compiler warning flags
* `EnableRuntimeSanitizers` module, which provides a function that enables ASAN, TSAN, and UBSAN based on options
* Write all final build outputs (executables and libraries) to `${PROJECT_BINARY_DIR}/artifacts`
* Automatically export all symbols from all libraries when building Windows DLLs
#### Repository features
* Build dependencies in the README
* Build instructions in the README
* Test instructions in the README
* Attribution in the README
[Unreleased]: https://gitlab.com/bravelytyped/crucible
[0.6.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.6.0
[0.5.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.5.0
[0.4.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.4.0
[0.3.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.3.0
[0.2.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.2.0
[0.1.0]: https://gitlab.com/bravelytyped/crucible/-/tree/v0.1.0
[`C4180`]: https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4180?view=msvc-170