Skip to content

nonstd-lite/indirect-lite

Repository files navigation

indirect-lite

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

Language License Build Status Version download Try it on godbolt online

Contents

Example usage

#include "nonstd/indirect.hpp"
#include <array>

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

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

    Vector dst = src;

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

Compile and run

$ 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 for use with C++11 and later. If and when available, the standard library is used, unless configured 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. It contains portions of the reference implementation by the The Indirect Value Authors, which has MIT copyright.

Dependencies

indirect lite has no other dependencies than the C++ standard library.

Installation

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

Synopsis

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, issuing indirect-main.t --pass @.

There's no standard documentation available yet at cppreference for class indirect, which is proposed to be part of the C++ dynamic memory management library.

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
operatorX(indirect & lhs, indirect & rhs)
(extension)
    template<...> constexpr bool
operatorX(indirect & lhs, std::nullptr_t)
(extension)
    template<...> constexpr bool
operatorX(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(), indirect lite supports the tweak header 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. 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. C++ on Sea 2022.

Other implementations of indirect

J.B. Coe. Reference implementation at value_types. Value types for composite class design. GitHub.
A previous version is archived at indirect_value.

Notes and references

W. Brown. n3339: A Preliminary Proposal for a Deep-Copying Smart Pointer, Walter E. Brown, 2012.
J.B. Coe. p0201: polymorphic_value: A Polymorphic Value Type for C++, 2022.
J.B. Coe. p1950: indirect_value: A Free-Store-Allocated Value Type For C++, 2022.
J.B. Coe. 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 (PPT). 2003.
R. Grimm. Visiting a std::variant with the Overload Pattern. 2021.
H. Hinnant. “Incomplete types and shared_ptr / unique_ptr”. 2011.
M. Knejp. p0316: allocate_unique and allocator_delete.
H. Sutter. "Pimpls - Beauty Marks You Can Depend On", 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. 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

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]

About

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

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors