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

https://github.com/martinmoene/observer-ptr-lite

observer-ptr - An observer_ptr for C++98 and later in a single-file header-only library (Extensions for Library Fundamentals, v2, v3)
https://github.com/martinmoene/observer-ptr-lite

cpp17 cpp98 header-only no-dependencies observer-ptr single-file

Last synced: 9 months ago
JSON representation

observer-ptr - An observer_ptr for C++98 and later in a single-file header-only library (Extensions for Library Fundamentals, v2, v3)

Awesome Lists containing this project

README

          

# observer_ptr<> for C++98 up

[![Language](https://img.shields.io/badge/C%2B%2B-98/11/14/17-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/observer-ptr-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/observer-ptr-lite/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/6icjotc617wmhljt/branch/master?svg=true)](https://ci.appveyor.com/project/martinmoene/observer-ptr/branch/master) [![Version](https://badge.fury.io/gh/martinmoene%2Fobserver-ptr.svg)](https://github.com/martinmoene/observer-ptr/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/observer-ptr/master/include/nonstd/observer_ptr.h) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://conan.io/center/observer-ptr-lite) [![Vcpkg](https://img.shields.io/badge/on-vcpkg-blue.svg)](https://vcpkg.link/ports/observer-ptr-lite) [![Try it online](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/31XA2ReBGNDnplYK) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/jwVx39)

*observer-ptr* is a single-file header-only library with a variant of std::experimental::observer_ptr [[1](#ref1)] for C++98 and later.

**Contents**
- [Example usage](#example-usage)
- [In a nutshell](#in-a-nutshell)
- [License](#license)
- [Dependencies](#dependencies)
- [Installation](#installation)
- [Building the tests](#building-the-tests)
- [Synopsis](#synopsis)
- [Other open source implementations](#other-open-source-implementations)
- [Notes and references](#notes-and-references)
- [Appendix](#appendix)

Example usage
-------------
```Cpp
#include "nonstd/observer_ptr.hpp"

using namespace nonstd;

void use( observer_ptr p )
{
assert( *p == 42 );
}

int main()
{
int a = 42;
observer_ptr p( &a );
use( p );
}
```

### Compile and run

```
prompt>g++ -std=c++03 -Wall -I../include -o 01-basic.exe 01-basic.cpp && 01-basic.exe
```

In a nutshell
-------------
**observer-ptr** is an implementation of the *world’s dumbest smart pointer* for C++98 and higher. It takes no ownership responsibility for the object it *observes* or *watches* and is intended as a near drop-in replacement for raw pointer types. As a vocabulary type it indicates intended use, easing code reading ([Note 1](#note1)).

Class template `observer_ptr<>` has been proposed for inclusion into the C++ standard [1] and is part of Extensions for Library Fundamentals v2/v3 [[2](#ref2)][[3](#ref3)].

The *observer-ptr* of this project can be used with probably any clang, g++ or MSVC compiler. It has been tested with clang 3.4, g++ 5.2 and with VC6 (VS6, no comparison of observers), VC8 (VS2005), VC10 (VS2010), VC11 (VS2012), VC12 (VS2013), VC14 (VS2015).

License
-------
*observer-ptr* is distributed under the [Boost Software License](LICENSE.txt).

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

Installation
------------
*observer-ptr* is a single-file header-only library. Put [observer_ptr.h](include/nonstd/observer_ptr.h) in the [include](include) folder directly into the project source tree or somewhere reachable from your project.

Building the tests
------------------
To build the tests you need:

- [CMake](http://cmake.org), version 2.8.7 or later to be installed and in your PATH.
- A [suitable compiler](#reported-to-work-with).

The [*lest* test framework](https://github.com/martinmoene/lest) is included in the [test folder](test).

The following steps assume that the [*observer-ptr* source code](https://github.com/martinmoene/observer-ptr) has been cloned into a directory named `c:\observer-ptr`.

1. Create a directory for the build outputs for a particular architecture.
Here we use c:\observer-ptr\build-win-x86-vc10.

cd c:\observer-ptr
md build-win-x86-vc10
cd build-win-x86-vc10

2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list).

cmake -G "Visual Studio 10 2010" ..

3. Build the test suite in the Debug configuration (alternatively use Release).

cmake --build . --config Debug

4. Run the test suite.

ctest -V -C Debug

All tests should pass, indicating your platform is supported and you are ready to use *observer-ptr*.

Synopsis
--------

**Contents**
[Documentation of `std::experimental::observer_ptr`](#documentation-of-stdobserver_ptr)
[Configuration macros](#configuration-macros)

### Documentation of `std::experimental::observer_ptr`

Depending on the compiler and C++-standard used, `nonstd::observer_ptr` behaves less or more like `std::experimental::observer_ptr`. To get an idea of the capabilities of `nonstd::observer_ptr` with your configuration, look at the output of the [tests](test/observer_ptr.t.cpp), issuing `observer_ptr-main.t --pass @`. For `std::experimental::observer_ptr`, see its [documentation at cppreference](https://en.cppreference.com/w/cpp/experimental/observer_ptr) [[5](#ref5)].

### Configuration macros

#### Standard selection macro
\-Dnsop\_CPLUSPLUS=199711L
Define this macro to override the auto-detection of the supported C++ standard, or if your compiler does not set the `__cplusplus` macro correctly.

#### Select `std::experimental::observer_ptr` or `nonstd::observer_ptr`
At default, *observer-ptr lite* uses `std::experimental::observer_ptr` if it is available and lets you use it via namespace `nonstd`. You can however override this default and explicitly request to use `std::experimental::observer_ptr` or *observer-ptr lite*'s `nonstd::observer_ptr` as `nonstd::observer_ptr` via the following macros.

-Dnsop\_CONFIG\_SELECT\_OBSERVER_PTR=nsop_OBSERVER_PTR_DEFAULT
Define this to `nsop_OBSERVER_PTR_STD` to select `std::experimental::observer_ptr` as `nonstd::observer_ptr`. Define this to `nsop_OBSERVER_PTR_NONSTD` to select `nonstd::observer_ptr` as `nonstd::observer_ptr`. Default is undefined, which has the same effect as defining to `nsop_OBSERVER_PTR_DEFAULT`.

#### Conversions

\-Dnsop\_CONFIG\_ALLOW\_IMPLICIT\_CONVERSION\_FROM_SMART\_PTR=0
Allow implicit conversion from `std::unique_ptr` and `std::shared_ptr`. This is an extension to the proposal. Each of these implicit conversions can also be activated separately, see below. Default is 0.

\-Dnsop\_CONFIG\_ALLOW\_IMPLICIT\_CONVERSION\_FROM\_UNIQUE\_PTR=0
Allow implicit conversion from `std::unique_ptr`. This is an extension to the proposal. Default is 0.

\-Dnsop\_CONFIG\_ALLOW\_IMPLICIT\_CONVERSION\_FROM\_SHARED\_PTR=0
Allow implicit conversion from `std::shared_ptr`. This is an extension to the proposal. Default is 0.

\-Dnsop\_CONFIG\_ALLOW\_IMPLICIT\_CONVERSION\_TO\_UNDERLYING\_TYPE=0
The proposed `observer_ptr` provides [explicit conversions](http://en.cppreference.com/w/cpp/language/explicit) to `bool` and to the underlying type. Explicit conversion is not available from pre-C++11 compilers. To prevent problems due to unexpected [implicit conversions](http://en.cppreference.com/w/cpp/language/implicit_cast) to `bool` or to the underlying type, this library does not provide these implicit conversions at default. If you still want them, define this macro to 1. Without these implicit conversions enabled, a conversion to bool via the [safe bool idiom](https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool) is provided. Default is 0.

#### Compile-time tests

\-Dnsop\_CONFIG\_CONFIRMS\_COMPILATION\_ERRORS=0
Define this macro to 1 to experience the by-design compile-time errors of the *observer-ptr* components in the test suite. Default is 0.

Other open source implementations
---------------------------------
- Anthony Williams. [object_ptr - a safer replacement for raw pointers](https://www.justsoftwaresolutions.co.uk/cplusplus/object_ptr.html) (Boost License).
- Mário Feroldi. [observer_ptr implementation in C++17 (Library Fundamentals TS v2)](https://github.com/feroldi/observer_ptr) (MIT License).
- Joseph Thomson. [observer and optional_ref for the Guideline Support Library](https://github.com/hpesoj/gsl-pointers) (MIT License).

Notes and references
--------------------
### Notes
Note 1. This conclusion may be challenged if the coding style ensures that *any raw pointer* is a *non-owning pointer* [[4](#ref4)].

### References
[1] Walter E. Brown. [N3840: A Proposal for the World’s Dumbest Smart Pointer, v4](http://wg21.link/n4282) ([v1](http://wg21.link/n3514), [v2](http://wg21.link/n3740), [v3](http://wg21.link/n3840), [v4](http://wg21.link/n4282) (PDF). 19 December 2012 - 7 November 2014.
[2] N4481: Tentative Working Draft, C++ Extensions for Library Fundamentals, Version 2, [Section 4.2 Non-owning pointers](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4481.html#memory.observer.ptr). 12 April 2015.
[3] N4758: Working Draft, C++ Extensions for Library Fundamentals, Version 3, [Section 5.2 Non-owning pointers](https://rawgit.com/cplusplus/fundamentals-ts/v3/fundamentals-ts.html#memory.observer.ptr). 13 November 2018.
[4] Bjarne Stroustrup. [P1408: Abandon observer_ptr](http://wg21.link/p1408). 4 January 2018.
[5] ISO C++ Standard - Future Proposals. [shared_ptr and unique_ptr should both implicitly convert to observer_ptr](https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/7gsM7DaPWds/wlvOWH06CQAJ). 24 October 2018.
[6] Joseph Thomson. [Pointers and the C++ Core Guidelines](https://github.com/hpesoj/gsl-pointers#pointers-and-the-c-core-guidelines). 9 February 2017.
[7] C++ Core Guidelines. [Issue 847: Pointers and the C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/issues/847). 9 February 2017.
[8] Boost developers' mailing list. [Is there any interest in non-owning pointer-like types?](http://boost.2283326.n4.nabble.com/Is-there-any-interest-in-non-owning-pointer-like-types-tp4691421.html) 1 February 2017.
[9] cppreference.com. [std::experimental::observer_ptr](http://en.cppreference.com/w/cpp/experimental/observer_ptr).

Appendix
--------

### A.1 Compile-time information

The version of *observer-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 Observer Ptr test specification

```
Disallows to delete the observer_ptr unless implicit conversion allowed
Disallows construction from an observer_ptr of incompatible type
Disallows implicit conversion to bool unless implicit conversion allowed
Disallows implicit conversion to underlying type unless implicit conversion allowed
Disallows comparison to an observer_ptr with a different underlying type
Allows default construction
Allows construction from nullptr
Allows construction from a non-null pointer
Allows construction from an observer_ptr of compatible type
Allows implicit move-construction from a std::unique_ptr<> [smart-ptr][extension]
Allows implicit construction from a std::shared_ptr<> [smart-ptr][extension]
Allows to retrieve the pointer
Allows to retrieve the value pointed to
Allows to retrieve the member pointed to
Allows to test for a non-null pointer via conversion to bool
Allows to convert to the observed pointer [underlying-type][extension]
Allows to release to stop observing
Allows to reset to stop observing
Allows to reset to observe another pointer
Allows to swap two observers
Specialized: Allows to swap two observers
Specialized: Allows to make an observer
Specialized: Allows to compare if an observer is equal to another observer
Specialized: Allows to compare if an observer is equal to another observer with a related watched type
Specialized: Allows to compare if an observer is not equal to another observer
Specialized: Allows to compare if an observer is not equal to another observer with a related watched type
Specialized: Allows to compare if an observer is equal to nullptr
Specialized: Allows to compare if an observer is not equal to nullptr
Specialized: Allows to compare if an observer is less than another observer
Specialized: Allows to compare if an observer is less than another observer with a related watched type
Specialized: Allows to compare if an observer is less than or equal to another observer
Specialized: Allows to compare if an observer is less than or equal to another observer with a related watched type
Specialized: Allows to compare if an observer is greater than another observer
Specialized: Allows to compare if an observer is greater than another observer with a related watched type
Specialized: Allows to compare if an observer is greater than or equal to another observer
Specialized: Allows to compare if an observer is greater than or equal to another observer with a related watched type
Specialized: Allows to compute hash
```