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
Contents
- Example usage
- In a nutshell
- License
- Dependencies
- Installation
- Synopsis
- Building the tests
- Notes and references
- Appendix
#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";
}
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
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).
optional bare is distributed under the Boost Software License.
optional bare has no other dependencies than the C++ standard library.
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.
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 |
-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.
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
.
-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.
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
.
-
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
-
Configure CMake to use the compiler of your choice (run
cmake --help
for a list).cmake -G "Visual Studio 10 2010" ..
-
Build the test suite in the Debug configuration (alternatively use Release).
cmake --build . --config Debug
-
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.
[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.
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]
.
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