Skip to content

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

License

Notifications You must be signed in to change notification settings

martinmoene/indirect-value-lite

Repository files navigation

indirect-value-lite

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

Language License Build Status Version download Try it on godbolt online

Contents

Example usage

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

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

int main()
{
    Vector src = nonstd::make_indirect_value<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_value lite is a single-file header-only library to provide indirect_value 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_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. It contains portions of the reference implementation by the The Indirect Value Authors, which has MIT copyright.

Dependencies

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

Installation

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

Synopsis

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

There's no standard documentation available yet at cppreference for class indirect_value, 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_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
operatorX(indirect_value & lhs, indirect_value & rhs)
(extension)
    template<...> constexpr bool
operatorX(indirect_value & lhs, std::nullptr_t)
(extension)
    template<...> constexpr bool
operatorX(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(), indirect_value lite supports the tweak header 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. 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. An indirect value-type for C++. GitHub.

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++.
J.B. Coe. 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 (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_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

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]

About

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published