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

https://github.com/nonstd-lite/indirect-lite

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

Last synced: 15 days ago
JSON representation

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

Awesome Lists containing this project

README

          

# indirect-lite

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

[![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.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)
- [Presentations](#presentations)
- [Other implementations of indirect](#other-implementations-of-indirect)
- [Notes and references](#notes-and-references)
- [Appendix](#appendix)

## Example usage

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

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

int main()
{
Vector src = nonstd::make_indirect( 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 lite** is a single-file header-only library to provide `indirect` 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 lite** are ease of installation (single header), freedom of dependencies other than the standard library. *indirect 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 lite** are ... \[*to be summed up*\].

## License

*indirect 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/blob/main/LICENSE.txt).

## Dependencies

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

## Installation

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

## Synopsis

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

### Documentation of class indirect

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

There's no standard documentation available yet at cppreference for [`class indirect`](https://en.cppreference.com/w/cpp/???/indirect), 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** |   |
| Error reporting | class **bad_indirect_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 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**() noexcept | default-construct |
|   |   | constexpr explicit **indirect**(T * p, C c=C{}, D d=D{}) | construct, own given pointer |
|   |   | constexpr **indirect**(indirect const & other) | copy-construct from other |
|   |   | constexpr **indirect**(indirect && other) noexcept | move-construct from other |
|   |   | template<class ...T>
constexpr **indirect**(nonstd_lite_in_place_t(T), Ts &&... ts) | in-place construct |
|   |   | constexpr ~**indirect**() | destroy current object |
| Assignment
  |   | constexpr indirect &
**operator=**(indirect const & rhs) | copy-assign from other |
|   |   | constexpr indirect &
**operator=**(indirect && rhs) noexcept | move-assign from other |
| Modifiers |   | constexpr void **swap**(indirect & 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 lite*

| Kind | Std | Function | Result |
| ------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------ | ---------------------------- |
| Create
  |   | template<...> constexpr indirect
**make_indirect**(Ts&&... ts) | in-place construct
  |
|   |   | template<...> constexpr indirect
**allocate_indirect**(std::allocator_arg_t, A & a, Ts &&... ts) | in-place construct
  |
| Swap |   | void **swap**(indirect & lhs, indirect & rhs) | exchange contents |
| Relational operators
  |   | template<...> constexpr bool
operator**X**(indirect & lhs, indirect & rhs) | (extension) |
|   |   | template<...> constexpr bool
operator**X**(indirect & lhs, std::nullptr_t) | (extension) |
|   |   | template<...> constexpr bool
operator**X**(std::nullptr_t, indirect & 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 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.tweak.hpp` in a folder in the include-search-path. In the tweak header, provide definitions as documented below, like `#define indirect_CPLUSPLUS 201103L`.

#### Select `std::indirect` or `nonstd::indirect`

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

#### Standard selection macro

\-Dindirect\_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).

## Presentations

Jonathan Coe. [Vocabulary Types for Composite Class Design](https://youtu.be/sjLRX4WMvlU?si=1_cfQGG2142i5VJo). C++ on Sea 2022.

## Other implementations of indirect

J.B. Coe. Reference implementation at [value_types](https://github.com/jbcoe/value_types). Value types for composite class design. GitHub.
A previous version is archived at [indirect_value](https://github.com/jbcoe/indirect_value).

## 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++, 2022.
J.B. Coe. [p1950](http://wg21.link/p1950): indirect_value: A Free-Store-Allocated Value Type For C++, 2022.
J.B. Coe. [p3019](http://wg21.link/p3019): indirect and polymorphic: Vocabulary Types for Composite Class Design, 2025. P3019r14 was accepted in the Hagenburg meeting in 2025 for inclusion in C++26.
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 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 lite test specification

click to expand

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