Ideally we'd just do this when we need it, but the ostream derivation
will be controlled by both global config and per-structure config, so
it's hard to know exactly when we need it and when we don't.
Using operator= is not quite sound in presence of destructors and operator
overloading.
It's perfectly fine to assume that the left-hand-side of an operator= expression
is valid memory, however we're using uninitialized memory here, that may not be
the case.
Use placement new to properly construct tagged unions. I don't need this with
any urgency, but it's the right thing to do in presence of complex types, and
the current code seems a bomb waiting to explode :)
Currently, `cbindgen` uses the `--all-features` flag when expanding a
dependent crate. However, this may not be desirable in a number of
cases:
- Some C APIs may be gated by a feature flag and would not be present
in the final cdylib depending on the features provided (for instance
one could want to have the ability to build a "debug" version of the
library which provides extra unstable hooks). In such cases, a
programmatic `cbindgen` call in a build script would want to use only
the features that will get used in the current build.
- Some features may bring in large dependencies and/or potentially
increase compilation time without affecting the FFI surface, and it
would be faster and more efficient to disable them when running
`cbindgen`.
- Some features may require external libraries and/or hardware (e.g.
dependencies on GPU libraries such as CUDA) that may not be available
on the current machine without affecting the FFI surface.
To alleviate this problem, this PR adds an extended version of the
`parse.expand` configuration key, allowing control over the features
used when expanding in a way similar to the way cargo handles extended
dependencies (although note that there is a single version of each key,
since the features refer to the features of the current crate). So for
instance instead of writing `expand = ["euclid"]` one would write:
```
[parse.expand]
crates = ["euclid"]
```
which is equivalent to:
```
[parse.expand]
crates = ["euclid"]
all_features = false
default_features = true
features = ["feature1", "feature2"]
```
Note that `all_features` is set to `false` by default in order to match
cargo's behavior.
For backwards compatibility, the old syntax `expand = ["euclid"]` is
still supported and is equivalent to:
```
[parse.expand]
crates = ["euclid"]
all_features = true
default_features = true
features = null
```
In this case, `all_features` is set to `true` in order to match the
previous behavior of cbindgen.