Git Product home page Git Product logo

optional's Introduction

optional

Single header implementation of std::optional with functional-style extensions and support for references.

Documentation Status Clang + GCC: Linux Build Status MSVC: Windows Build Status

std::optional is the preferred way to represent an object which may or may not have a value. Unfortunately, chaining together many computations which may or may not produce a value can be verbose, as empty-checking code will be mixed in with the actual programming logic. This implementation provides a number of utilities to make coding with optional cleaner.

For example, instead of writing this code:

std::optional<image> get_cute_cat (const image& img) {
    auto cropped = crop_to_cat(img);
    if (!cropped) {
      return std::nullopt;
    }

    auto with_tie = add_bow_tie(*cropped);
    if (!with_tie) {
      return std::nullopt;
    }

    auto with_sparkles = make_eyes_sparkle(*with_tie);
    if (!with_sparkles) {
      return std::nullopt;
    }

    return add_rainbow(make_smaller(*with_sparkles));
}

You can do this:

tl::optional<image> get_cute_cat (const image& img) {
    return crop_to_cat(img)
           .and_then(add_bow_tie)
           .and_then(make_eyes_sparkle)
           .map(make_smaller)
           .map(add_rainbow);
}

The interface is the same as std::optional, but the following member functions are also defined. Explicit types are for clarity.

  • map: carries out some operation on the stored object if there is one.
    • tl::optional<std::size_t> s = opt_string.map(&std::string::size);
  • and_then: like map, but for operations which return a tl::optional.
    • tl::optional<int> stoi (const std::string& s);
    • tl::optional<int> i = opt_string.and_then(stoi);
  • or_else: calls some function if there is no value stored.
    • opt.or_else([] { throw std::runtime_error{"oh no"}; });
  • map_or: carries out a map if there is a value, otherwise returns a default value.
    • tl::optional<std::size_t> s = opt_string.map_or(&std::string::size, 0);
  • map_or_else: carries out a map if there is a value, otherwise returns the result of a given default function.
    • std::size_t get_default();
    • tl::optional<std::size_t> s = opt_string.map_or_else(&std::string::size, get_default);
  • conjunction: returns the argument if a value is stored in the optional, otherwise an empty optional.
    • tl::make_optional(42).conjunction(13); //13
    • tl::optional<int>{}.conjunction(13); //empty
  • disjunction: returns the argument if the optional is empty, otherwise the current value.
    • tl::make_optional(42).disjunction(13); //42
    • tl::optional<int>{}.disjunction(13); //13
  • take: returns the current value, leaving the optional empty.
    • opt_string.take().map(&std::string::size); //opt_string now empty;

In addition to those member functions, optional references are also supported:

int i = 42;
tl::optional<int&> o = i;
*o == 42; //true
i = 12;
*o == 12; //true
&*o == &i; //true

Assignment has rebind semantics rather than assign-through semantics:

int j = 8;
o = j;

&*o == &j; //true

Compiler support

Tested on:

  • Linux
    • clang 6.0.1
    • clang 5.0.2
    • clang 4.0.1
    • clang 3.9
    • clang 3.8
    • clang 3.7
    • clang 3.6
    • clang 3.5
    • g++ 8.0.1
    • g++ 7.3
    • g++ 6.4
    • g++ 5.5
    • g++ 4.9
    • g++ 4.8
  • Windows
    • MSVC 2015
    • MSVC 2017

Standards Proposal

This library also serves as an implementation of WG21 standards paper P0798R0: Monadic operations for std::optional. This paper proposes adding map, and_then, and or_else to std::optional.


CC0

To the extent possible under law, Sy Brand has waived all copyright and related or neighboring rights to the optional library. This work is published from: United Kingdom.

optional's People

Contributors

basiliscos avatar bruxisma avatar decoyrs avatar denizevrenci avatar glynos avatar idragnev avatar johvik avatar kbenzie avatar mortenfyhn avatar rollbear avatar tartanllama avatar thephd avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.