/optional-bare

optional bare - A simple version of a C++17-like optional for default-constructible, copyable types, for C++98 and later in a single-file header-only library

Primary LanguageC++Boost Software License 1.0BSL-1.0

optional bare: A simple single-file header-only version of a C++17-like optional for default-constructible, copyable types, for C++98 and later

Language License Build Status Build status Version download Conan Try it online Try it on godbolt online

Contents

Example usage

#include "nonstd/optional.hpp"

#include <cstdlib>
#include <iostream>

using nonstd::optional;
using nonstd::nullopt;

optional<int> to_int( char const * const text )
{
    char * pos = NULL;
    const int value = strtol( text, &pos, 0 );

    return pos == text ? nullopt : optional<int>( value );
}

int main( int argc, char * argv[] )
{
    char * text = argc > 1 ? argv[1] : "42";

    optional<int> oi = to_int( text );

    if ( oi ) std::cout << "'" << text << "' is " << *oi;
    else      std::cout << "'" << text << "' isn't a number";
}

Compile and run

prompt>g++ -Wall -Wextra -std=c++03 -I../include -o 01-to_int.exe 01-to_int.cpp && 01-to_int x1
'x1' isn't a number

In a nutshell

optional bare is a single-file header-only library to represent optional (nullable) objects and pass them by value. optional bare is derived from optional lite. Like optional like, optional bare aims to provide a C++17-like optional for use with C++98 and later. Unlike optional lite, optional bare is limited to default-constructible and copyable types.

Features and properties of optional bare are ease of installation (single header), freedom of dependencies other than the standard library.

Not provided are emplace() or other operations that require move semantics. optional bare does not support reference-type optionals and it does not handle overloaded address of operators.

For more examples, see this answer on StackOverflow [6] and the quick start guide [7] of Boost.Optional (note that its interface differs from optional bare).

License

optional bare is distributed under the Boost Software License.

Dependencies

optional bare has no other dependencies than the C++ standard library.

Installation

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

Synopsis

For the interface of std::optional, see cppreference.

optional bare uses C++98 only, it does not differentiate its compatibility with std::optional based on compiler and standard library support of C++11 and later. optional bare does not control whether functions participate in overload resolution based on the value type.

The following table gives an overview of what is not provided by optional bare.

Kind Item Remark
Types in_place_t move-semantics not supported
  in_place_type_t  
  in_place_index_t  
Tags in_place  
  in_place_type  
  in_place_index  
Methods    
Construction optional( optional&& other )  
  template <class U>
optional( optional<U>&& other )
 
  template<class U = value_type>
optional( U&& value )
provides optional( T const & )
  template<...>
optional( std::in_place_t, ...)
 
Assignment optional & operator=( optional&& other )  
  template <class U>
optional & operator=( optional<U>&& other )
 
  template<class U = value_type>
optional & operator=( U&& value )
provides operator=( T const & )
Modifiers template<...>
T& emplace(...)
move-semantics not supported
Free functions template<...>
optional<T> make_optional( ... && )
no forwarding, only provides
make_optional( T const & )
Other std::hash<nonstd::optional> std::hash<> requires C++11

Configuration

Standard selection macro

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

Select std::optional or nonstd::optional

At default, optional lite uses std::optional if it is available and lets you use it via namespace nonstd. You can however override this default and explicitly request to use std::optional or optional lite's nonstd::optional as nonstd::optional via the following macros.

-Doptional_CONFIG_SELECT_OPTIONAL=variant_OPTIONAL_DEFAULT
Define this to optional_OPTIONAL_STD to select std::optional as nonstd::optional. Define this to optional_OPTIONAL_NONSTD to select nonstd::optional as nonstd::optional. Default is undefined, which has the same effect as defining to optional_OPTIONAL_DEFAULT.

Disable exceptions

-Doptional_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.

Building the tests

To build the tests you need:

  • CMake, version 2.8.12 or later to be installed and in your PATH.
  • A compiler that supports C++98 or later.

The lest test framework is included in the test folder.

The following steps assume that the optional bare source code has been cloned into a directory named c:\optional-bare.

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

     cd c:\optional-bare
     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 optional bare.

Notes and references

[1] CppReference. Optional.

[2] ISO/IEC WG21. N4606, section 20.6 Optional objects. July 2016.

[3] Fernando Cacciola, Andrzej Krzemieński. A proposal to add a utility class to represent optional objects (Revision 5).

[4] Andrzej Krzemieński. optional (nullable) objects for C++14. Reference implementation on GitHub.

[5] Simon Brand. P0798R0: Monadic operations for std::optional.

[6] Simon Brand. C++11/14/17 std::optional with functional-style extensions . Reference implementation on GitHub.

[7] Fernando Cacciola. Boost.Optional library.

[8] StackOverflow. How should one use std::optional?. Answer by Timothy Shields. 31 May 2013.

[9] Fernando Cacciola. Boost.Optional Quick start guide.

Appendix

A.1 Compile-time information

The version of optional bare 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 Optional Bare test specification

optional: Allows to default construct an empty optional
optional: Allows to explicitly construct a disengaged, empty optional via nullopt
optional: Allows to copy-construct from empty optional
optional: Allows to copy-construct from non-empty optional
optional: Allows to copy-construct from literal value
optional: Allows to copy-construct from value
optional: Allows to copy-construct from optional with different value type
optional: Allows to copy-construct from empty optional with different value type
optional: Allows to assign nullopt to disengage
optional: Allows to copy-assign from/to engaged and disengaged optionals
optional: Allows to copy-assign from literal value
optional: Allows to copy-assign from value
optional: Allows to copy-assign from optional with different value type
optional: Allows to copy-assign from empty optional with different value type
optional: Allows to swap with other optional (member)
optional: Allows to obtain pointer to value via operator->()
optional: Allows to obtain value via operator*()
optional: Allows to obtain engaged state via has_value()
optional: Allows to obtain has_value() via operator bool()
optional: Allows to obtain value via value()
optional: Allows to obtain value or default via value_or()
optional: Throws bad_optional_access at disengaged access
optional: Allows to reset content
optional: Allows to swap engage state and values (non-member)
optional: Provides relational operators
optional: Provides mixed-type relational operators
make_optional: Allows to copy-construct optional