151 lines
6.5 KiB
Plaintext
151 lines
6.5 KiB
Plaintext
libfit
|
|
|
|
Source: https://fuchsia.googlesource.com/fuchsia/+/main/sdk/lib/fit/
|
|
Version: 36303cd2d1611cb1b670235692d01a92e83ecd21
|
|
License:
|
|
|
|
Copyright 2019 The Fuchsia Authors.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are
|
|
met:
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above
|
|
copyright notice, this list of conditions and the following disclaimer
|
|
in the documentation and/or other materials provided with the
|
|
distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
======
|
|
|
|
FIT is a lean library of portable C++ abstractions for control flow and
|
|
memory management beyond what is offered by the C++ 17 standard library.
|
|
|
|
FIT only depends on the C++ language and standard library, including some C++17
|
|
library features. It offers essential enhancements to the C++ standard library
|
|
rather than attempting to replace it or become a framework for writing
|
|
applications. FIT can be thought of as an "annex" that expresses a few ideas
|
|
we wish the C++ standard library might itself implement someday.
|
|
|
|
FIT is lean.
|
|
|
|
## What Belongs in FIT
|
|
|
|
Several Fuchsia SDK libraries, such as *libfidl*, depend on FIT and on the C++
|
|
standard library. As these libraries are broadly used, we must take care in
|
|
deciding what features to include in FIT to avoid burdening developers with
|
|
unnecessary code or dependencies.
|
|
|
|
In general, the goal is to identify specific abstractions that make sense to
|
|
generalize across the entire ecosystem of Fuchsia C++ applications. These will
|
|
necessarily be somewhat low-level but high impact. We don't want to add code to
|
|
FIT simply because we think it's cool. We need evidence that it is a common
|
|
idiom and that a broad audience of developers will significantly benefit from
|
|
its promotion.
|
|
|
|
Here are a few criteria to consider:
|
|
|
|
- Is the feature lightweight, general-purpose, and platform-independent?
|
|
- Is the feature not well served by other means, particularly by the C++
|
|
standard library?
|
|
- Is the feature needed by a Fuchsia SDK library?
|
|
- Does the feature embody a beneficial idiom that clients of the Fuchsia SDK
|
|
commonly use?
|
|
- Has the feature been re-implemented many times already leading to code
|
|
fragmentation that we would like to eliminate?
|
|
|
|
If in doubt, leave it out. See [Justifications] below.
|
|
|
|
## What Doesn't Belong in FIT
|
|
|
|
FIT is not intended to become a catch-all class library.
|
|
|
|
Specifically prohibited features:
|
|
|
|
- Features that introduce dependencies on libraries other than the C and C++
|
|
standard library.
|
|
- Features that only work on certain operating systems.
|
|
- Collection classes where the C++ 17 standard library already offers an
|
|
adequate (if not perfect) alternative.
|
|
- Classes that impose an implementation burden on clients such as event loops,
|
|
dispatchers, frameworks, and other glue code.
|
|
|
|
## Implementation Considerations
|
|
|
|
FIT is not exception safe (but could be made to be in the future).
|
|
|
|
## Style Conventions
|
|
|
|
The API style was modified to fit current android::base library conventions.
|
|
|
|
In brief:
|
|
|
|
- Class identifiers are CamelCase
|
|
- Class methods and variable identifiers use "camelCase", class fields use
|
|
"mCamelCase".
|
|
- Template parameters are `CamelCase`.
|
|
- Preprocessor macros are `UPPER_SNAKE_CASE`.
|
|
|
|
## Justifications
|
|
|
|
These sections explain why certain features are in FIT.
|
|
|
|
### fit::Function
|
|
|
|
- *libfidl*'s API needs a callable function wrapper with move semantics but
|
|
C++ 14's `std::function` only supports copyable function objects which forces
|
|
FIDL to allocate callback state on the heap making programs less efficient
|
|
and harder to write.
|
|
- Lots of other C++ code uses callbacks extensively and would benefit from move
|
|
semantics for similar reasons.
|
|
- So we should create a move-only function wrapper to use everywhere.
|
|
|
|
### fit::Defer
|
|
|
|
- When writing asynchronous event-driven programs, it can become challenging
|
|
to ensure that resources remain in scope for the duration of an operation
|
|
in progress and are subsequently released.
|
|
- The C++ 14 standard library offers several classes with RAII semantics, such
|
|
as `std::unique_ptr`, which are helpful in these situations. Unfortunately the
|
|
C++ 14 standard library does not offer affordances for easily invoking a
|
|
function when a block or object goes out of scope short of implementing a
|
|
new class from scratch.
|
|
- We have observed several re-implementations of the same idea throughout the
|
|
system.
|
|
- So we should create a simple way to invoke a function on scope exit.
|
|
|
|
### fit::Nullable
|
|
|
|
- Case study: fit::defer has a need to store a closure that may be nullable.
|
|
We were able to replace its hand-rolled lifetime management code with
|
|
fit::nullable thereby vastly simplifying its implementation.
|
|
- Case study: fit::future has a need to track its own validity along with
|
|
a continuation that may or not be present.
|
|
- Case study: We have previously observed bugs where developers were
|
|
surprised when assigning a null closure to wrappers such as fit::function
|
|
fit::defer, or fit::future left these objects in a supposedly "valid"
|
|
but uninvocable state. These objects therefore take care to detect
|
|
null closures and enter an "invalid" state. Using fit::is_null and
|
|
fit::nullable makes it easier to eliminate this redundant state and
|
|
simplifies the API for clients of these wrappers.
|
|
- std::optional can be effective here but it doesn't directly handle nullity
|
|
so it takes more care to coalesce the null and "not present" states.
|
|
std::optional also increases the size of the object to carry an extra
|
|
bool and passing, whereas fit::nullable eliminates this overhead by
|
|
taking advantage of the underlying value's null state (if there is one).
|
|
- So we introduce fit::nullable to handle both cases systematically while
|
|
still hewing close to the semantics of std::optional.
|