Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/martinmoene/indirect-value-lite

indirect_value lite – An indirect value-type for C++11 and later in a single-file header-only library (p1950)
https://github.com/martinmoene/indirect-value-lite

Last synced: 2 months ago
JSON representation

indirect_value lite – An indirect value-type for C++11 and later in a single-file header-only library (p1950)

Awesome Lists containing this project

README

        

# indirect-value-lite

indirect_value lite – An indirect value-type for C++11 and later in a single-file header-only library (p1950)

[![Language](https://img.shields.io/badge/C%2B%2B-11/14/17/20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/indirect-value-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/indirect-value-lite/actions/workflows/ci.yml) [![Version](https://badge.fury.io/gh/martinmoene%2Findirect-value-lite.svg)](https://github.com/martinmoene/indirect-value-lite/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://github.com/martinmoene/indirect-value-lite/blob/master/include/nonstd/indirect_value.hpp) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/s9j8njMM9)

**Contents**

- [Example usage](#example-usage)
- [In a nutshell](#in-a-nutshell)
- [License](#license)
- [Dependencies](#dependencies)
- [Installation](#installation)
- [Synopsis](#synopsis)
- [Other implementations of indirect_value](#other-implementations-of-indirect_value)
- [Notes and references](#notes-and-references)
- [Appendix](#appendix)

## Example usage

```Cpp
#include "nonstd/indirect_value.hpp"
#include

using stdarr = std::array< int, 10 >;
using Vector = nonstd::indirect_value< stdarr >;

int main()
{
Vector src = nonstd::make_indirect_value( stdarr( {0, 1, 2, 3, 4, 5, 6, 42} ) );

Vector dst = src;

return (*dst)[7]; // or:dst.value()[7]
}
```

### Compile and run

```Text
$ g++ -std=c++17 -Wall -I../include/ -o 01-basic.exe 01-basic.cpp & 01-basic.exe
$ echo $?
42
```

## In a nutshell

**indirect_value lite** is a single-file header-only library to provide `indirect_value` type proposed for [C++23](http://wg21.link/p1950) for use with C++11 and later. If and when available, the standard library is used, unless [configured](#configuration) otherwise.

**Features and properties of indirect_value lite** are ease of installation (single header), freedom of dependencies other than the standard library. *indirect_value lite* shares the approach to in-place tags with any-lite, expected-lite, optional-lite and with variant-lite and these libraries can be used together.

**Limitations of indirect_value lite** are ... \[*to be summed up*\].

## License

*indirect_value lite* is distributed under the [Boost Software License](https://github.com/martinmoene/indirect-value-lite/blob/master/LICENSE.txt). It contains portions of the reference implementation by the *The Indirect Value Authors*, which has [MIT copyright](https://github.com/jbcoe/indirect_value/blob/main/LICENSE.txt).

## Dependencies

*indirect_value lite* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header).

## Installation

*indirect_value lite* is a single-file header-only library. Put `indirect_value.hpp` in the [include](include) folder directly into the project source tree or somewhere reachable from your project.

## Synopsis

- [Documentation of `class indirect_value`](#documentation-of-class-indirect_value)
- [Configuration](#configuration)

### Documentation of class indirect_value

\[*Envisioned*\] Depending on the compiler and C++ standard used, *indirect_value lite* behaves less or more like the standard's version. To get an idea of the capabilities of *indirect_value lite* with your configuration, look at the output of the [tests](test/indirect_value.t.cpp), issuing `indirect_value-main.t --pass @`.

There's no standard documentation available yet at cppreference for [`class indirect_value`](https://en.cppreference.com/w/cpp/???/indirect_value), which is proposed to be part of the [C++ dynamic memory management library](https://en.cppreference.com/w/cpp/memory).

#### Types and values in namespace nonstd

| Purpose | Type / value | Notes |
| --------------------- | ------------------------------------- | ----------------------------------------------- |
| Indirect value type | class **indirect_value** |   |
| Error reporting | class **bad_indirect_value_access** | (extension) |
| Hash | class **std::hash** | specialisation (extension) |
|   |   |   |
| In-place construction | struct **in_place_tag** |   |
|   | **in_place** | select type or index for in-place construction |
|   | **in_place_type** | select type for in-place construction |
|  (variant) | **in_place_index** | select index for in-place construction |
|   | **in_place_t** | type or index for in-place construction |
|   | **in_place_type_t** | type for in-place construction |
|  (variant) | **in_place_index_t** | index for in-place construction |
|   | **nonstd_lite_in_place**( T) | macro for alias template in_place |
|   | **nonstd_lite_in_place_type**( T) | macro for alias template in_place_type<T> |
|  (variant) | **nonstd_lite_in_place_index**( T ) | macro for alias template in_place_index<T> |
|   | **nonstd_lite_in_place_t**( T) | macro for alias template in_place_t |
|   | **nonstd_lite_in_place_type_t**( T) | macro for alias template in_place_type_t<T> |
|  (variant) | **nonstd_lite_in_place_index_t**( T ) | macro for alias template in_place_index_t<T> |

#### Interface of *indirect_value lite*

| Kind | Std | Method | Result |
| -------------------- | ------ | ----------------------------------------------------------------------------------------------- | ---------------------------- |
| Types |   | **value_type** | T template type |
|   |   | **copier_type** | C template type (extension) |
|   |   | **deleter_type** | D template type (extension) |
| Construction |   | constexpr **indirect_value**() noexcept | default-construct |
|   |   | constexpr explicit **indirect_value**(T * p, C c=C{}, D d=D{}) | construct, own given pointer |
|   |   | constexpr **indirect_value**(indirect_value const & other) | copy-construct from other |
|   |   | constexpr **indirect_value**(indirect_value && other) noexcept | move-construct from other |
|   |   | template<class ...T>
constexpr **indirect_value**(nonstd_lite_in_place_t(T), Ts &&... ts) | in-place construct |
|   |   | constexpr ~**indirect_value**() | destroy current object |
| Assignment
  |   | constexpr indirect_value &
**operator=**(indirect_value const & rhs) | copy-assign from other |
|   |   | constexpr indirect_value &
**operator=**(indirect_value && rhs) noexcept | move-assign from other |
| Modifiers |   | constexpr void **swap**(indirect_value & other) noexcept(...) | exchange objects |
| Observers |   | constexpr T& **operator***() & | owned object |
|   |   | constexpr T const & **operator***() const & | owned object |
|   |   | constexpr T && **operator***() && noexcept | owned object |
|   |   | constexpr T const && **operator***() const && noexcept | owned object |
|   |   | constexpr T * **operator->**() noexcept | owned object |
|   |   | constexpr T const * **operator->**() const noexcept | owned object |
|   |   | constexpr explicit **operator bool**() const noexcept | engaged |
|   |   | constexpr bool **has_value**() const noexcept | engaged (extension) |
|   |   | constexpr T & **value**() & | may throw (extension) |
|   |   | constexpr T const & **value**() const & | may throw (extension) |
|   |   | constexpr T && **value**() && | may throw (extension) |
|   |   | constexpr T const && **value**() const && | may throw (extension) |
|   |   | constexpr copier_type & **get_copier**() noexcept | (extension) |
|   |   | constexpr copier_type const & **get_copier**() const noexcept | (extension) |
|   |   | constexpr deleter_type & **get_deleter**() noexcept | (extension) |
|   |   | constexpr deleter_type const & **get_deleter**() const noexcept | (extension) |

#### Algorithms for *indirect_value lite*

| Kind | Std | Function | Result |
| ------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------- |
| Create
  |   | template<...> constexpr indirect_value
**make_indirect_value**(Ts&&... ts) | in-place construct
  |
|   |   | template<...> constexpr indirect_value
**allocate_indirect_value**(std::allocator_arg_t, A & a, Ts &&... ts) | in-place construct
  |
| Swap |   | void **swap**(indirect_value & lhs, indirect_value & rhs) | exchange contents |
| Relational operators
  |   | template<...> constexpr bool
operator**X**(indirect_value & lhs, indirect_value & rhs) | (extension) |
|   |   | template<...> constexpr bool
operator**X**(indirect_value & lhs, std::nullptr_t) | (extension) |
|   |   | template<...> constexpr bool
operator**X**(std::nullptr_t, indirect_value & rhs) | (extension) |
| Three-way operators | C++20
  | template<...> constexpr bool
operator**<=>**(...) | (extension)
  |

### Configuration

#### Tweak header

If the compiler supports [`__has_include()`](https://en.cppreference.com/w/cpp/preprocessor/include), *indirect_value lite* supports the [tweak header](https://vector-of-bool.github.io/2020/10/04/lib-configuration.html) mechanism. Provide your *tweak header* as `nonstd/indirect_value.tweak.hpp` in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like `#define indirect_value_CPLUSPLUS 201103L`.

#### Select `std::indirect_value` or `nonstd::indirect_value`

The C++ standard does not yet provide type `std::indirect_value`.

#### Standard selection macro

\-Dindirect_value\_CPLUSPLUS=201103L
Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the `__cplusplus` macro correctly.

#### Disable extensions

-Dnsiv\_CONFIG\_NO\_EXTENSIONS=0
Define this to 1 if you want to compile without extensions with respect to [p1950r2 of October 2022](http://wg21.link/p1950r2). See below. Default is undefined, and all extensions are enabled.

#### Disable reference qualified operators extension

-Dnsiv\_CONFIG\_NO\_EXTENSION\_REF\_QUALIFIED\_OPERATORS=0
Define this to 1 if you want to compile without this extension. Default is undefined (extension enabled).

#### Disable `value()` members extension

-Dnsiv\_CONFIG\_NO\_EXTENSION\_VALUE\_MEMBERS=0
Define this to 1 if you want to compile without this extension. Default is undefined (extension enabled).

#### Disable `get_copier()`, `get_deleter()` extension

-Dnsiv\_CONFIG\_NO\_EXTENSION\_GET\_CPY\_DEL\_MEMBERS=0
Define this to 1 if you want to compile without this extension. Default is undefined (extension enabled).

#### Disable relational operators extension

-Dnsiv\_CONFIG\_NO\_EXTENSION\_RELATIONAL\_OPERATORS=0
Define this to 1 if you want to compile without this extension. Default is undefined (extension enabled).

#### Disable `std::hash` extension

-Dnsiv\_CONFIG\_NO\_EXTENSION\_STD\_HASH=0
Define this to 1 if you want to compile without this extension. Default is undefined (extension enabled).

## Other implementations of indirect_value

J.B. Coe. Reference implementation: [indirect_value](https://github.com/jbcoe/indirect_value). An indirect value-type for C++. GitHub.

## Notes and references

W. Brown. [n3339](http://wg21.link/n3339): A Preliminary Proposal for a Deep-Copying Smart Pointer, Walter E. Brown, 2012.
J.B. Coe. [p0201](http://wg21.link/p0201): polymorphic_value: A Polymorphic Value Type for C++.
J.B. Coe. [p1950](http://wg21.link/p1950): indirect_value: A Free-Store-Allocated Value Type For C++.
J. Coplien. Advanced C++ Programming Styles and Idioms (Addison-Wesley), James O. Coplien. 1992.
C. Ericson. [Memory Optimization, Christer Ericson, Games Developers Conference](http://realtimecollisiondetection.net/pubs/GDC03_Ericson_Memory_Optimization.ppt) (PPT). 2003.
R. Grimm. [Visiting a std::variant with the Overload Pattern](https://www.modernescpp.com/index.php/visiting-a-std-variant-with-the-overload-pattern). 2021.
H. Hinnant. “[Incomplete types and shared_ptr / unique_ptr](http://howardhinnant.github.io/incomplete.html)”. 2011.
M. Knejp. [p0316](http://wg21.link/p0316): allocate_unique and allocator_delete.
H. Sutter. "[Pimpls - Beauty Marks You Can Depend On](http://www.gotw.ca/publications/mill04.htm)", Herb Sutter. 1998.
S. Meyers. Effective Modern C++, Item 22: When using the Pimpl Idiom, define special member functions in the implementation file, Scott Meyers. 2014.
A. Upadyshev. [PIMPL, Rule of Zero and Scott Meyers, Andrey Upadyshev](http://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html). 2015.

## Appendix


### A.1 Compile-time information

The version of *indirect_value lite* is available via tag `[.version]`. The following tags are available for information on the compiler and on the C++ standard library used: `[.compiler]`, `[.stdc++]`, `[.stdlanguage]` and `[.stdlibrary]`.


### A.2 indirect_value lite test specification

click to expand

```Text
indirect_value: Allows to default construct (empty)
indirect_value: Allows to construct from pointer
indirect_value: Allows to in-place construct from arguments
indirect_value: Allows to copy-construct
indirect_value: Allows to move-construct
indirect_value: Allows to copy-assign
indirect_value: Allows to move-assign
indirect_value: Allows to swap (value)
indirect_value: Allows to swap (copier)
indirect_value: Allows to swap (deleter)
indirect_value: Allows to obtain value, operator->()
indirect_value: Allows to obtain value, operator->() const
indirect_value: Allows to obtain value, operator*() &
indirect_value: Allows to obtain value, operator*() const &
indirect_value: Allows to obtain value, operator*() &&
indirect_value: Allows to obtain value,operator*() const &&
indirect_value: Allows to check if engaged, operator bool()
indirect_value: Allows to check if engaged, has_value() [extension]
indirect_value: Allows to obtain value, value() & [extension]
indirect_value: Allows to obtain value, value() const & [extension]
indirect_value: Allows to obtain value, value() && [extension]
indirect_value: Allows to obtain value, value() const && [extension]
indirect_value: No throw of exception on valid value access, value() & [extension]
indirect_value: No throw of exception on valid value access, value() const & [extension]
indirect_value: No throw of exception on valid value access, value() && [extension]
indirect_value: No throw of exception on valid value access, value() const && [extension]
indirect_value: Throws on bad value access, value() & [extension]
indirect_value: Throws on bad value access, value() const & [extension]
indirect_value: Throws on bad value access, value() && [extension]
indirect_value: Throws on bad value access, value() const && [extension]
indirect_value: Allows to obtain copier, get_copier() & [extension]
indirect_value: Allows to obtain copier, get_copier() const & [extension]
indirect_value: Allows to obtain deleter, get_deleter() & [extension]
indirect_value: Allows to obtain deleter, get_deleter() const & [extension]
indirect_value: Ensure using minimum space requirements
indirect_value: Ensure noexcept of observers
indirect_value: Ensure ref- and const-qualifier of observers
indirect_value: Ensure properties of bad_indirect_value_access [extension]
indirect_value: Ensure stats of copy and delete type
indirect_value: Ensure protection against reentrancy
indirect_value: Ensure protection against self-assign
indirect_value: Ensure using source copier when copying
indirect_value: Ensure working with an incomplete type
make_indirect_value(): Allows to in-place construct an indirect value from parameters
allocate_indirect_value(): Allows to in-place construct an indirect value from parameters, with given allocator
swap(): Allows to swap
relational operators: Allows to compare indirect_value-s [extension]
relational operators: Allows to compare indirect_value with nullptr [extension]
relational operators: Allows to compare indirect_value with value convertible to its value_type [extension]
relational operators: Allows to 3-way compare indirect_value-s [extension]
relational operators: Allows to 3-way compare indirect_value with nullptr [extension]
relational operators: Allows to 3-way compare indirect_value with value convertible to its value_type [extension]
std::hash: Allows to hash an indirect_value [extension]
tweak header: reads tweak header if supported [tweak]
```