{"id":15047261,"url":"https://github.com/martinmoene/optional-bare","last_synced_at":"2025-04-10T00:50:55.466Z","repository":{"id":53744963,"uuid":"109379380","full_name":"martinmoene/optional-bare","owner":"martinmoene","description":"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","archived":false,"fork":false,"pushed_at":"2022-12-03T12:55:31.000Z","size":118,"stargazers_count":20,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T02:37:07.571Z","etag":null,"topics":["cpp98","header-only","no-dependencies","optional","optional-implementations","single-file"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinmoene.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-03T09:50:54.000Z","updated_at":"2024-05-01T20:53:47.000Z","dependencies_parsed_at":"2023-01-22T16:10:14.822Z","dependency_job_id":null,"html_url":"https://github.com/martinmoene/optional-bare","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Foptional-bare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Foptional-bare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Foptional-bare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinmoene%2Foptional-bare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinmoene","download_url":"https://codeload.github.com/martinmoene/optional-bare/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137999,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp98","header-only","no-dependencies","optional","optional-implementations","single-file"],"created_at":"2024-09-24T20:55:50.934Z","updated_at":"2025-04-10T00:50:55.438Z","avatar_url":"https://github.com/martinmoene.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 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\n\n[![Language](https://img.shields.io/badge/C%2B%2B-98-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/optional-bare/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/optional-bare/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/xl1lrm4cfdi08431?svg=true)](https://ci.appveyor.com/project/martinmoene/optional-bare) [![Version](https://badge.fury.io/gh/martinmoene%2Foptional-bare.svg)](https://github.com/martinmoene/optional-bare/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://raw.githubusercontent.com/martinmoene/optional-bare/master/include/nonstd/optional.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://bintray.com/martinmoene/nonstd-lite/optional-bare%3Anonstd-lite/_latestVersion) [![Try it online](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/zPhGkdPVU1OpHnu8) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/SUQtFb)\n\n**Contents**  \n- [Example usage](#example-usage)\n- [In a nutshell](#in-a-nutshell)\n- [License](#license)\n- [Dependencies](#dependencies)\n- [Installation](#installation)\n- [Synopsis](#synopsis)\n- [Building the tests](#building-the-tests)\n- [Notes and references](#notes-and-references)\n- [Appendix](#appendix)\n\n\nExample usage\n-------------\n```Cpp\n#include \"nonstd/optional.hpp\"\n\n#include \u003ccstdlib\u003e\n#include \u003ciostream\u003e\n\nusing nonstd::optional;\nusing nonstd::nullopt;\n\noptional\u003cint\u003e to_int( char const * const text )\n{\n    char * pos = NULL;\n    const int value = strtol( text, \u0026pos, 0 );\n\n    return pos == text ? nullopt : optional\u003cint\u003e( value );\n}\n\nint main( int argc, char * argv[] )\n{\n    char * text = argc \u003e 1 ? argv[1] : \"42\";\n\n    optional\u003cint\u003e oi = to_int( text );\n\n    if ( oi ) std::cout \u003c\u003c \"'\" \u003c\u003c text \u003c\u003c \"' is \" \u003c\u003c *oi;\n    else      std::cout \u003c\u003c \"'\" \u003c\u003c text \u003c\u003c \"' isn't a number\";\n}\n```\n### Compile and run\n```\nprompt\u003eg++ -Wall -Wextra -std=c++03 -I../include -o 01-to_int.exe 01-to_int.cpp \u0026\u0026 01-to_int x1\n'x1' isn't a number\n```\nIn a nutshell\n---------------\n**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](https://github.com/martinmoene/optional-lite). Like *optional like*, *optional bare* aims to provide a [C++17-like optional](http://en.cppreference.com/w/cpp/utility/optional) for use with C++98 and later. Unlike *optional lite*, *optional bare* is limited to default-constructible and copyable types. \n\n**Features and properties of optional bare** are ease of installation (single header), freedom of dependencies other than the standard library.\n\n**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.\n\nFor 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*).\n\n\nLicense\n-------\n*optional bare* is distributed under the [Boost Software License](LICENSE.txt).\n \n\nDependencies\n------------\n*optional bare* has no other dependencies than the [C++ standard library](http://en.cppreference.com/w/cpp/header).\n\n\nInstallation\n------------\n*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.\n\n\nSynopsis\n--------\nFor the interface of `std::optional`, see [cppreference](http://en.cppreference.com/w/cpp/utility/optional).\n\n*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.\n\nThe following table gives an overview of what is **not provided** by *optional bare*.\n\n| Kind         | Item                 | Remark |\n|--------------|----------------------|--------|\n| **Types**    | **in_place_t**       |move-semantics not supported|\n|\u0026nbsp;        | **in_place_type_t**  |\u0026nbsp;|\n|\u0026nbsp;        | **in_place_index_t** |\u0026nbsp;|\n| **Tags**     | **in_place**         |\u0026nbsp;|\n|\u0026nbsp;        | **in_place_type**    |\u0026nbsp;|\n|\u0026nbsp;        | **in_place_index**   |\u0026nbsp;|\n| **Methods**  |\u0026nbsp;|\u0026nbsp;| \n| Construction | **optional**( optional\u0026\u0026 other ) |\u0026nbsp;|\n|\u0026nbsp;        | template \u0026lt;class U\u003e\u003cbr\u003e**optional**( optional\u0026lt;U\u003e\u0026\u0026 other ) |\u0026nbsp;|\n|\u0026nbsp;        | template\u0026lt;class U = value_type\u003e\u003cbr\u003e**optional**( U\u0026\u0026 value ) |provides optional( T const \u0026 )|\n|\u0026nbsp;        | template\u0026lt;...\u003e\u003cbr\u003e**optional**( std::in_place_t, ...) |\u0026nbsp;|\n| Assignment   | optional \u0026 **operator=**( optional\u0026\u0026 other ) |\u0026nbsp;|\n|\u0026nbsp;        | template \u0026lt;class U\u003e\u003cbr\u003eoptional \u0026 **operator=**( optional\u0026lt;U\u003e\u0026\u0026 other ) |\u0026nbsp;|\n|\u0026nbsp;        | template\u0026lt;class U = value_type\u003e\u003cbr\u003eoptional \u0026 **operator=**( U\u0026\u0026 value ) |provides operator=( T const \u0026 )|\n| Modifiers    | template\u0026lt;...\u003e\u003cbr\u003eT\u0026 **emplace**(...)  | move-semantics not supported |\n| **Free functions** | template\u0026lt;...\u003e\u003cbr\u003eoptional\u0026lt;T\u003e **make_optional**(  ... \u0026\u0026 ) |no forwarding, only provides\u003cbr\u003emake_optional( T const \u0026 )|\n| **Other**    | std::**hash**\u0026lt;nonstd::optional\u003e | std::hash\u003c\u003e requires C++11|\n\n\n### Configuration\n\n#### Standard selection macro\n\\-D\u003cb\u003eoptional\\_CPLUSPLUS\u003c/b\u003e=199711L  \nDefine this macro to override the auto-detection of the supported C++ standard, if your compiler does not set the `__cplusplus` macro correctly.\n\n#### Select `std::optional` or `nonstd::optional`\nAt 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.\n\n-D\u003cb\u003eoptional\\_CONFIG\\_SELECT\\_OPTIONAL\u003c/b\u003e=variant_OPTIONAL_DEFAULT  \nDefine 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`.\n\n#### Disable exceptions\n-D\u003cb\u003eoptional_CONFIG_NO_EXCEPTIONS\u003c/b\u003e=0\nDefine 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.\n\n\nBuilding the tests\n------------------\nTo build the tests you need:\n\n- [CMake](http://cmake.org), version 2.8.12 or later to be installed and in your PATH.\n- A compiler that supports C++98 or later.\n\nThe [*lest* test framework](https://github.com/martinmoene/lest)  is included in the [test folder](test).\n\nThe 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`.\n\n1. Create a directory for the build outputs for a particular architecture.\nHere we use c:\\optional-bare\\build-win-x86-vc10.\n\n        cd c:\\optional-bare\n        md build-win-x86-vc10\n        cd build-win-x86-vc10\n\n2. Configure CMake to use the compiler of your choice (run `cmake --help` for a list).\n\n        cmake -G \"Visual Studio 10 2010\" ..\n\n3. Build the test suite in the Debug configuration (alternatively use Release).    \n\n        cmake --build . --config Debug\n\n4. Run the test suite.    \n\n        ctest -V -C Debug\n\nAll tests should pass, indicating your platform is supported and you are ready to use *optional bare*.\n\n\nNotes and references\n--------------------\n[1] CppReference. [Optional](http://en.cppreference.com/w/cpp/utility/optional).  \n\n[2] ISO/IEC WG21. [N4606, section 20.6 Optional objects](http://wg21.link/n4606). July 2016.\n\n[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).\n\n[4] Andrzej Krzemieński. [optional (nullable) objects for C++14](https://github.com/akrzemi1/Optional). Reference implementation on GitHub.\n\n[5] Simon Brand. [P0798R0: Monadic operations for std::optional](https://wg21.tartanllama.xyz/monadic-optional).\n\n[6] Simon Brand. [C++11/14/17 std::optional with functional-style extensions ](https://github.com/TartanLlama/optional). Reference implementation on GitHub.\n\n[7] Fernando Cacciola. [Boost.Optional library](http://www.boost.org/doc/libs/1_49_0/libs/optional/doc/html/index.html).\n\n[8] StackOverflow. [How should one use std::optional?](http://stackoverflow.com/a/16861022). Answer by Timothy Shields. 31 May 2013.\n\n[9] 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).\n\n\nAppendix\n--------\n\n### A.1 Compile-time information\n\nThe 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]`.\n\n### A.2 Optional Bare test specification\n\n```\noptional: Allows to default construct an empty optional\noptional: Allows to explicitly construct a disengaged, empty optional via nullopt\noptional: Allows to copy-construct from empty optional\noptional: Allows to copy-construct from non-empty optional\noptional: Allows to copy-construct from literal value\noptional: Allows to copy-construct from value\noptional: Allows to copy-construct from optional with different value type\noptional: Allows to copy-construct from empty optional with different value type\noptional: Allows to assign nullopt to disengage\noptional: Allows to copy-assign from/to engaged and disengaged optionals\noptional: Allows to copy-assign from literal value\noptional: Allows to copy-assign from value\noptional: Allows to copy-assign from optional with different value type\noptional: Allows to copy-assign from empty optional with different value type\noptional: Allows to swap with other optional (member)\noptional: Allows to obtain pointer to value via operator-\u003e()\noptional: Allows to obtain value via operator*()\noptional: Allows to obtain engaged state via has_value()\noptional: Allows to obtain has_value() via operator bool()\noptional: Allows to obtain value via value()\noptional: Allows to obtain value or default via value_or()\noptional: Throws bad_optional_access at disengaged access\noptional: Allows to reset content\noptional: Allows to swap engage state and values (non-member)\noptional: Provides relational operators\noptional: Provides mixed-type relational operators\nmake_optional: Allows to copy-construct optional\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinmoene%2Foptional-bare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinmoene%2Foptional-bare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinmoene%2Foptional-bare/lists"}