Skip to content
value-ptr-lite - A C++ smart-pointer with value semantics for C++98, C++11 and later in a single-file header-only library
C++ Python CMake Batchfile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
cmake Replace underscore with dash in unit name Jun 16, 2019
example Replace underscore with dash in unit name Jun 16, 2019
include/nonstd Release 0.2.1 (Conan, thanks to @jgsogo) Apr 26, 2019
project/CodeBlocks
script
test
.buckconfig Add buck configuration Jun 17, 2017
.gitattributes
.gitignore Initial code May 31, 2017
.travis.yml Add cmake installation and config-file packaging Jan 1, 2019
BUCK Add buck configuration Jun 17, 2017
CHANGES.txt
CMakeLists.txt Replace underscore with dash in unit name Jun 16, 2019
LICENSE.txt
README.md [skip ci] Added `valuable` and search to section references Feb 21, 2019
appveyor.yml
conanfile.py

README.md

value-ptr lite: A C++ smart-pointer with value semantics for C++98, C++11 and later

Language License Build Status Build status Version download Conan

Contents

Pimpl example usage

// in header file:

#include "nonstd/value_ptr.hpp"

// Thanks to value_ptr we get value semantics for free:

struct Widget
{
   Widget( int x );

   int next();

   struct Pimpl;
   nonstd::value_ptr<Pimpl> ptr;
};

// in source file:

struct Widget::Pimpl
{
    int x;

    Pimpl( int v ) : x( v ) {}

    int next() { return ++x; }
};


Widget::Widget( int x ) : ptr( Widget::Pimpl( x ) ) {}  // or: ptr( x )

int Widget::next() { return ptr->next(); }

int main()
{
    Widget w1( 42 );
    Widget w2( w1 );

    assert( w1.next() == 43 );
    assert( w2.next() == 43 );
}

In a nutshell

value-ptr lite is a single-file header-only library to bring value semantics to heap resources. In certain situations, such as with the pimpl idiom in the example above, a pointer must be used while value semantics would be prefered. This is where value_ptr comes into play. A value_ptr is similar to a std::optional in many respects and one could say a value_ptr is more value than pointer.

This work is inspired on value_ptr by Gaetano Checinski [1] and on impl_ptr by Andrey Upadyshev [2].

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

Limitations of value-ptr lite are ... .

License

value-ptr lite is distributed under the Boost Software License.

Dependencies

value-ptr lite has no other dependencies than the C++ standard library.

Installation

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

Synopsis

Contents

Types in namespace nonstd

Purpose [1] [2] Type Notes
Smart pointer with
value semantics
class value_ptr [2]: impl_ptr
Error reporting class bad_value_access  
In-place construction struct in_place_tag  
  in_place select type or index for in-place construction
  nonstd_lite_in_place_type_t( T) macro for alias template in_place_type_t<T>
  nonstd_lite_in_place_index_t( T ) macro for alias template in_place_index_t<T>

Interface of value-ptr lite

Class value_ptr

Kind [1] [2] std Type / Method Note / Result
Value types   element_type  
    pointer  
    reference  
    const_pointer  
    const_reference  
Lifetime types   cloner_type [2]: copier_type
    deleter_type  
Construction   value_ptr() noexcept  
  C++11 value_ptr( std::nullptr_t ) noexcept  
    value_ptr( pointer p ) noexcept  
    value_ptr( value_ptr const & other )  
  C++11 value_ptr( value_ptr && other ) noexcept  
  1   value_ptr( element_type const & value )  
  1 C++11 value_ptr( element_type && value ) noexcept  
  C++11 template< class... Args >
explicit value_ptr( in_place_type_t(T), Args&&... args )
 
  C++11 template< class U, class... Args >
explicit value_ptr( in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
 
    value_ptr( cloner_type const & cloner )  
  C++11 value_ptr( cloner_type && cloner ) noexcept  
    value_ptr( deleter_type const & deleter )  
  C++11 value_ptr( deleter_type && deleter ) noexcept  
  C++11 template< class V, class ClonerOrDeleter >
value_ptr( V && value, ClonerOrDeleter && cloner_or_deleter )
 
  <C++11 template< class V, class ClonerOrDeleter >
value_ptr( V const & value, ClonerOrDeleter const & cloner_or_deleter )
 
  C++11 template< class V, class C, class D >
value_ptr( V && value, C && cloner, D && deleter )
 
  <C++11 template< class V, class C, class D >
value_ptr( V const & value, C const & cloner, D const & deleter )
 
Destruction C++11 ~value_ptr()  
Assignment C++11 value_ptr & operator=( std::nullptr_t ) noexcept  
    value_ptr & operator=( T const & value )  
  C++11 template< class U, ... >
value_ptr & operator=( U && value )
 
    value_ptr & operator=( value_ptr const & rhs )  
  C++11 value_ptr & operator=( value_ptr && rhs ) noexcept  
Emplace C++11 template< class... Args >
void emplace( Args&&... args )
 
  C++11 template< class U, class... Args >
void emplace( std::initializer_list<U> il, Args&&... args )
 
Observers   pointer get() noexcept  
    cloner_type & get_cloner() noexcept [2]: get_copier()
    deleter_type & get_deleter() noexcept  
    reference operator*() const  
    pointer operator->() const noexcept  
  C++11 explicit operator bool() const noexcept  
  <C++11 operator safe_bool() const noexcept  
    bool has_value() const nsvp_noexcept  
    element_type const & value() const  
    element_type & value()  
  C++11 template< class U >
constexpr element_type value_or( U && v ) const
 
  <C++11 template< class U >
constexpr element_type value_or( U const & v ) const
 
Modifiers   pointer release() noexcept  
    void reset( pointer p = pointer() ) noexcept  
    void swap( value_ptr & other ) noexcept  

Notes:

  1. [2] has various converting constructors.

Non-member functions for value-ptr lite

Kind [1] [2] std Function
Relational operators   template< ... >
bool operator op( value_ptr<...> const & lhs, value_ptr<...> const & rhs )
  C++11 template< ... >
bool operator op( value_ptr<...> const & lhs, std::nullptr_t )
  C++11 template< ... >
bool operator op( std::nullptr_t, value_ptr<...> const & rhs )
    template< ... >
bool operator op( value_ptr<...> const & lhs, T const & value )
    template< ... >
bool operator op( T const & value, value_ptr<...> const & rhs )
Swap   template< class T, class C, class D >
void swap( value_ptr<T,C,D> & x, value_ptr<T,C,D> & y ) noexcept(...)
Create <C++11 template< class T, class C, class D >
value_ptr<T,C,D> make_value( T const & v )
  C++11 template< class T >
value_ptr< typename std::decay<T>::type > make_value( T && v )
  C++11 template< class T, class...Args >
value_ptr<T,C,D> make_value( Args&&... args )
  C++11 template< class T, class U, class... Args >
value_ptr<T,C,D> make_value( std::initializer_list<U> il, Args&&... args )
Hash C++11 template< class T >
class hash< nonstd::value_ptr<T,C,D> >

Configuration macros

Standard selection macro

-Dnsvp_CPLUSPLUS=199711L
Define this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the __cpluplus macro correctly.

Compare pointers

-Dnsvp_CONFIG_COMPARE_POINTERS=0
Define this to 1 to compare value_ptr's pointer instead of the content it's pointing to. Default is 0.

Disable exceptions

-Dnsvp_CONFIG_NO_EXCEPTIONS=0
Define this to 1 if you want to compile without exceptions. If not defined, the header tries and detect if exceptions have been disabled (e.g. via -fno-exceptions). Default is undefined.

Reported to work with

The table below mentions the compiler versions value-ptr lite is reported to work with.

OS Compiler Versions
Windows Clang/LLVM ?
  GCC 5.2.0, 6.3.0
  Visual C++
(Visual Studio)
8 (2005), 10 (2010), 11 (2012),
12 (2013), 14 (2015, 2017)
GNU/Linux Clang/LLVM 3.1.0 - 4.0.0 (Wandbox)
  GCC 4.4.7 - 7.1.0 (Wandbox)
OS X ? ?

Building tests and examples

To build the tests and examples you need:

The lest test framework is included in the test folder.

The following steps assume that the value_ptr lite source code has been cloned into a directory named value-ptr-lite.

Buck

To run the tests and examples:

value-ptr-lite> buck run test
value-ptr-lite> buck run example:01-pimpl
value-ptr-lite> buck run example:02-tree

CMake

  1. Create a directory for the build outputs for a particular architecture. Here we use value-ptr-lite/build.

     value-ptr-lite> mkdir build && cd build
    
  2. Configure CMake to use the compiler of your choice (run cmake --help for a list).

     value-ptr-lite/build> cmake -G "Unix Makefiles" [see 3. below] ..
    
  3. Optional. You can control above configuration through the following options:

    • -DVALUE_PTR_LITE_BUILD_TEST=ON: build the tests for lest, default off
    • -DVALUE_PTR_LITE_BUILD_EXAMPLE=ON: build the examples, default off
    • -DVALUE_PTR_LITE_COLOURISE_TEST=ON: use colour for pass, fail, default off
  4. Build the test suite. With Visual Studio, append the configuration as --config Debug or --config Release.

     value-ptr-lite/build> cmake --build .
    
  5. Run the test suite.

     value-ptr-lite/build> ctest -V
    

All tests should pass, indicating your platform is supported and you are ready to use value-ptr lite. See the table with supported types and functions.

Other value-ptr implementations

Notes and references

[1] Gaetano Checinski. value_ptr — The Missing C++ Smart-pointer (GitHub). May 2017.
[2] Andrey Upadyshev. PIMPL, Rule of Zero and Scott Meyers (GitHub). December 29, 2015.

Appendix

A.1 Compile-time information

The version of value-ptr 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 Value-ptr lite test specification

value_ptr: Allows to default construct an empty value_ptr
value_ptr: Allows to explicitly construct a disengaged, empty value_ptr via nullptr
value_ptr: Allows to default construct an empty value_ptr with a non-default-constructible
value_ptr: Allows to copy-construct from empty value_ptr
value_ptr: Allows to copy-construct from non-empty value_ptr
value_ptr: Allows to move-construct from value_ptr (C++11)
value_ptr: Allows to copy-construct from literal value
value_ptr: Allows to copy-construct from value
value_ptr: Allows to move-construct from value (C++11)
value_ptr: Allows to in-place construct from literal value (C++11)
value_ptr: Allows to in-place copy-construct from value (C++11)
value_ptr: Allows to in-place move-construct from value (C++11)
value_ptr: Allows to in-place copy-construct from initializer-list (C++11)
value_ptr: Allows to in-place move-construct from initializer-list (C++11)
value_ptr: Allows to construct from pointer to value
value_ptr: Allows to assign nullptr to disengage (C++11)
value_ptr: Allows to copy-assign from/to engaged and disengaged value_ptr-s
value_ptr: Allows to move-assign from/to engaged and disengaged value_ptr-s (C++11)
value_ptr: Allows to copy-assign from literal value
value_ptr: Allows to copy-assign from value
value_ptr: Allows to move-assign from value (C++11)
value_ptr: Allows to copy-emplace content from arguments (C++11)
value_ptr: Allows to move-emplace content from arguments (C++11)
value_ptr: Allows to copy-emplace content from intializer-list and arguments (C++11)
value_ptr: Allows to move-emplace content from intializer-list and arguments (C++11)
value_ptr: Allows to construct and destroy via user-specified cloner and deleter
value_ptr: Allows to construct via user-specified cloner with member data
value_ptr: Allows to obtain pointer to value via operator->()
value_ptr: Allows to obtain value via operator*()
value_ptr: Allows to obtain moved-value via operator*()
value_ptr: Allows to obtain engaged state via operator bool()
value_ptr: Allows to obtain engaged state via has_value()
value_ptr: Allows to obtain value via value()
value_ptr: Allows to obtain value or default via value_or()
value_ptr: Allows to obtain moved-default via value_or() (C++11)
value_ptr: Throws bad_value_access at disengaged access
value_ptr: Allows to release its content
value_ptr: Allows to clear its content (reset)
value_ptr: Allows to replace its content (reset)
value_ptr: Allows to swap with other value_ptr (member)
value_ptr: Allows to swap with other value_ptr (non-member)
value_ptr: Provides relational operators (non-member, pointer comparison: nsvp_CONFIG_COMPARE_POINTERS!=0)
value_ptr: Provides relational operators (non-member, value comparison: nsvp_CONFIG_COMPARE_POINTERS==0)
value_ptr: Provides relational operators (non-member, mixed value comparison: nsvp_CONFIG_COMPARE_POINTERS==0)
make_value: Allows to copy-construct value_ptr
make_value: Allows to move-construct value_ptr (C++11)
make_value: Allows to in-place copy-construct value_ptr from arguments (C++11)
make_value: Allows to in-place move-construct value_ptr from arguments (C++11)
make_value: Allows to in-place copy-construct value_ptr from initializer-list and arguments (C++11)
make_value: Allows to in-place move-construct value_ptr from initializer-list and arguments (C++11)
std::hash<>: Allows to obtain hash (C++11)
You can’t perform that action at this time.