|
| 1 | +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 |
| 2 | +==================================================== |
| 3 | +[](https://isocpp.org/) [](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [](https://opensource.org/licenses/MIT) [](https://travis-ci.org/martinmoene/optional-bare) [](https://ci.appveyor.com/project/martinmoene/optional-bare) [](https://github.com/martinmoene/optional-bare/releases) [](https://raw.githubusercontent.com/martinmoene/optional-bare/master/include/nonstd/optional.hpp) [](https://wandbox.org/permlink/xxxxxxxxxxx) |
| 4 | + |
| 5 | +**Contents** |
| 6 | +- [Example usage](#example-usage) |
| 7 | +- [In a nutshell](#in-a-nutshell) |
| 8 | +- [License](#license) |
| 9 | +- [Dependencies](#dependencies) |
| 10 | +- [Installation](#installation) |
| 11 | +- [Synopsis](#synopsis) |
| 12 | +- [Building the tests](#building-the-tests) |
| 13 | +- [Notes and references](#notes-and-references) |
| 14 | +- [Appendix](#appendix) |
| 15 | + |
| 16 | + |
| 17 | +Example usage |
| 18 | +------------- |
| 19 | +```C++ |
| 20 | +#include "optional.hpp" |
| 21 | + |
| 22 | +#include <cstdlib> |
| 23 | +#include <iostream> |
| 24 | + |
| 25 | +using nonstd::optional; |
| 26 | +using nonstd::nullopt; |
| 27 | + |
| 28 | +optional<int> to_int( char const * const text ) |
| 29 | +{ |
| 30 | + char * pos = NULL; |
| 31 | + const int value = strtol( text, &pos, 0 ); |
| 32 | + |
| 33 | + return pos == text ? nullopt : optional<int>( value ); |
| 34 | +} |
| 35 | + |
| 36 | +int main( int argc, char * argv[] ) |
| 37 | +{ |
| 38 | + char * text = argc > 1 ? argv[1] : "42"; |
| 39 | + |
| 40 | + optional<int> oi = to_int( text ); |
| 41 | + |
| 42 | + if ( oi ) std::cout << "'" << text << "' is " << *oi; |
| 43 | + else std::cout << "'" << text << "' isn't a number"; |
| 44 | +} |
| 45 | +``` |
| 46 | +### Compile and run |
| 47 | +``` |
| 48 | +prompt>g++ -Wall -Wextra -std=c++03 -I.. -o to_int.exe to_int.cpp && to_int x1 |
| 49 | +'x1' isn't a number |
| 50 | +``` |
| 51 | +In a nutshell |
| 52 | +--------------- |
| 53 | +**optional bare** is a single-file header-only library to represent optional (nullable) objects and pass them by value. The library aims to provide a [C++17-like optional](http://en.cppreference.com/w/cpp/utility/optional) for default-constructible and copyable types for use with C++98 and later. *optional bare* is derived from [optional lite](https://github.com/martinmoene/optional-lite). |
| 54 | +
|
| 55 | +**Features and properties of optional bare** are ease of installation (single header), freedom of dependencies other than the standard library. |
| 56 | +
|
| 57 | +**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. |
| 58 | +
|
| 59 | +For more examples, see [this answer on StackOverflow](http://stackoverflow.com/a/16861022) [6] and the [quick start guide](http://www.boost.org/doc/libs/1_57_0/libs/optional/doc/html/boost_optional/quick_start.html) [7] of Boost.Optional (note that its interface differs from *optional bare*). |
| 60 | +
|
| 61 | +
|
| 62 | +License |
| 63 | +------- |
| 64 | +*variant bare* uses the [MIT](LICENSE) license. |
| 65 | + |
| 66 | +
|
| 67 | +Dependencies |
| 68 | +------------ |
| 69 | +*optional bare* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header). |
| 70 | +
|
| 71 | +
|
| 72 | +Installation |
| 73 | +------------ |
| 74 | +*optional bare* is a single-file header-only library. Put `optional.hpp` in the [include](include) folder directly into the project source tree or somewhere reachable from your project. |
| 75 | +
|
| 76 | +
|
| 77 | +Synopsis |
| 78 | +-------- |
| 79 | +For the interface of `std::optional`, see [cppreference](http://en.cppreference.com/w/cpp/utility/optional). |
| 80 | +
|
| 81 | +*optional bare* uses C++98 only, it does not differentiate its compatibility with `std::optional` based on compiler and standard library support. The following table lists what is **not provided** by *optional bare*. |
| 82 | +
|
| 83 | +| Kind | Item | Remark | |
| 84 | +|------|------------------|--------| |
| 85 | +| Types| in_place_t |move-semantics not supported| |
| 86 | +| | in_place_type_t | | |
| 87 | +| | in_place_index_t | | |
| 88 | +| Tags | in_place | | |
| 89 | +| | in_place_type | | |
| 90 | +| | in_place_index | | |
| 91 | +| Member functions | | | |
| 92 | +|  Construction | optional( optional&& other ) | | |
| 93 | +| | template <class U><br>optional( optional<U>&& other ) | | |
| 94 | +| | template<...><br>optional( std::in_place_t, ...) | | |
| 95 | +| | template<class U = value_type><br>optional( U&& value ) | | |
| 96 | +|  Modifiers | template<...><br>T& emplace(...) | move-semantics not supported | |
| 97 | +| Non-member functions | template<...><br>optional<T> make_optional( ... && ) |only for value_type, no forwarding | |
| 98 | +| Other | std::hash<nonstd::optional> | std::hash<> requires C++11| |
| 99 | +
|
| 100 | +
|
| 101 | +Building the tests |
| 102 | +------------------ |
| 103 | +To build the tests you need: |
| 104 | +
|
| 105 | +- [CMake](http://cmake.org), version 2.8.12 or later to be installed and in your PATH. |
| 106 | +- A compiler that supports C++98 or later. |
| 107 | +
|
| 108 | +The [*lest* test framework](https://github.com/martinmoene/lest) is included in the [test folder](test). |
| 109 | +
|
| 110 | +The following steps assume that the [*optional bare* source code](https://github.com/martinmoene/optional-bare) has been cloned into a directory named `c:\optional-bare`. |
| 111 | +
|
| 112 | +1. Create a directory for the build outputs for a particular architecture. |
| 113 | +Here we use c:\optional-bare\build-win-x86-vc10. |
| 114 | +
|
| 115 | + cd c:\optional-bare |
| 116 | + md build-win-x86-vc10 |
| 117 | + cd build-win-x86-vc10 |
| 118 | +
|
| 119 | +2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list). |
| 120 | +
|
| 121 | + cmake -G "Visual Studio 10 2010" .. |
| 122 | +
|
| 123 | +3. Build the test suite in the Debug configuration (alternatively use Release). |
| 124 | +
|
| 125 | + cmake --build . --config Debug |
| 126 | +
|
| 127 | +4. Run the test suite. |
| 128 | +
|
| 129 | + ctest -V -C Debug |
| 130 | +
|
| 131 | +All tests should pass, indicating your platform is supported and you are ready to use *optional bare*. |
| 132 | +
|
| 133 | +
|
| 134 | +Notes and references |
| 135 | +-------------------- |
| 136 | +[1] CppReference. [Optional](http://en.cppreference.com/w/cpp/utility/optional). |
| 137 | +
|
| 138 | +[2] ISO/IEC WG21. [N4606, section 20.6 Optional objects](http://wg21.link/n4606). July 2016. |
| 139 | +
|
| 140 | +[3] Fernando Cacciola, Andrzej Krzemieński. [A proposal to add a utility class to represent optional objects (Revision 5)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html). |
| 141 | +
|
| 142 | +[4] Andrzej Krzemieński. [optional (nullable) objects for C++14](https://github.com/akrzemi1/Optional). Reference implementation on GitHub. |
| 143 | +
|
| 144 | +[5] Fernando Cacciola. [Boost.Optional library](http://www.boost.org/doc/libs/1_49_0/libs/optional/doc/html/index.html). |
| 145 | +
|
| 146 | +[6] StackOverflow. [How should one use std::optional?](http://stackoverflow.com/a/16861022). Answer by Timothy Shields. 31 May 2013. |
| 147 | +
|
| 148 | +[7] Fernando Cacciola. [Boost.Optional Quick start guide](http://www.boost.org/doc/libs/1_57_0/libs/optional/doc/html/boost_optional/quick_start.html). |
| 149 | +
|
| 150 | +
|
| 151 | +Appendix |
| 152 | +-------- |
| 153 | +### A.1 Optional Bare test specification |
| 154 | +
|
| 155 | +``` |
| 156 | +optional: Allows to default construct an empty optional |
| 157 | +optional: Allows to explicitly construct a disengaged, empty optional via nullopt |
| 158 | +optional: Allows to copy-construct from empty optional |
| 159 | +optional: Allows to copy-construct from non-empty optional |
| 160 | +optional: Allows to copy-construct from literal value |
| 161 | +optional: Allows to copy-construct from value |
| 162 | +optional: Allows to copy-construct from optional with different value type |
| 163 | +optional: Allows to assign nullopt to disengage |
| 164 | +optional: Allows to copy-assign from/to engaged and disengaged optionals |
| 165 | +optional: Allows to copy-assign from literal value |
| 166 | +optional: Allows to copy-assign from value |
| 167 | +optional: Allows to copy-assign from optional with different value type |
| 168 | +optional: Allows to swap with other optional (member) |
| 169 | +optional: Allows to obtain pointer to value via operator->() |
| 170 | +optional: Allows to obtain value via operator*() |
| 171 | +optional: Allows to obtain engaged state via has_value() |
| 172 | +optional: Allows to obtain has_value() via operator bool() |
| 173 | +optional: Allows to obtain value via value() |
| 174 | +optional: Allows to obtain value or default via value_or() |
| 175 | +optional: Throws bad_optional_access at disengaged access |
| 176 | +optional: Allows to reset content |
| 177 | +optional: Allows to swaps engage state and values (non-member) |
| 178 | +optional: Provides relational operators |
| 179 | +make_optional: Allows to copy-construct optional |
| 180 | +``` |
0 commit comments