Awesome
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
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><br>optional( optional<U>&& other ) | ||
template<class U = value_type><br>optional( U&& value ) | provides optional( T const & ) | |
template<...><br>optional( std::in_place_t, ...) | ||
Assignment | optional & operator=( optional&& other ) | |
template <class U><br>optional & operator=( optional<U>&& other ) | ||
template<class U = value_type><br>optional & operator=( U&& value ) | provides operator=( T const & ) | |
Modifiers | template<...><br>T& emplace(...) | move-semantics not supported |
Free functions | template<...><br>optional<T> make_optional( ... && ) | no forwarding, only provides<br>make_optional( T const & ) |
Other | std::hash<nonstd::optional> | std::hash<> requires C++11 |
Configuration
Standard selection macro
-D<b>optional_CPLUSPLUS</b>=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.
-D<b>optional_CONFIG_SELECT_OPTIONAL</b>=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
-D<b>optional_CONFIG_NO_EXCEPTIONS</b>=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
.
-
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.
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