• Stars
    star
    793
  • Rank 57,419 (Top 2 %)
  • Language
    C++
  • License
    Creative Commons ...
  • Created about 7 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

C++11/14/17 std::optional with functional-style extensions and reference support

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.

More Repositories

1

expected

C++11/14/17 std::expected with functional-style extensions
C++
1,307
star
2

minidbg

A mini x86 linux debugger for teaching purposes
C++
507
star
3

vizh

An esoteric visual language that takes image files as input based on a multi-tape turing machine, designed for compatibility with C.
Python
229
star
4

function_ref

A lightweight, non-owning reference to a callable.
C++
168
star
5

typeclasses

Future C++ implementation of Rust-like trait objects with no boilerplate
C++
116
star
6

cpp-documentation-example

An example of setting up Sphinx for C++ and building with CMake and Read the Docs
CMake
85
star
7

actions-eleventy

GitHub Action for generating a static website with Eleventy
Shell
84
star
8

non-binary

πŸ’›β™‘β™₯πŸ’œ
Isabelle
76
star
9

ranges

Ranges that didn't make C++20
C++
73
star
10

generator

Single-header, ranges-compatible generator type built on C++20 coroutines
C++
57
star
11

tl

A bunch of small C++ utilities
C++
54
star
12

caginator

TypeScript
43
star
13

secret-hitler-strategies

Unofficial Secret Hitler strategy guide
HTML
34
star
14

etkf

Embarrassingly templated keyboard framework
C
32
star
15

enjamb

An esoteric programming language where it's not what's in your lines that matters β€” it's where you break them.
C++
29
star
16

dltrace

A demonstration of tracing dynamic library loading and unloading on Linux.
C++
15
star
17

tartanllama.github.io

CSS
15
star
18

piscrn

A screenshot server, library, and command-line utility for the Raspberry Pi
C
12
star
19

advent-of-code-2020

Rust
11
star
20

lameduck

Terrible Brainfuck to x64 compiler developed live in an hour
C++
11
star
21

aoc-2021

C++
7
star
22

writing-a-linux-debugger

7
star
23

icu-emscripten

Binaries and headers for ICU built for Emscripten
C
7
star
24

aoc-2022

C++
5
star
25

koura

A C++ text template engine.
C++
5
star
26

cppquiz17

Porting questions on cppquiz.org to C++17
C++
4
star
27

rustcpp

Rust
4
star
28

tl-docs

Documentation for the tl libraries
Python
4
star
29

jork

C++
4
star
30

li1I

A domain-specific programming language for integer calculations. Includes LLVM-based compiler.
C++
4
star
31

cppcon-cmake

CMake
3
star
32

cpppaperbot

Python
3
star
33

amer

A C++17 static website generator
CSS
3
star
34

tl-cmake

CMake
3
star
35

advent-of-code-2018

C++
3
star
36

retroman

LaTeX template for writing retro-style technical manuals
TeX
3
star
37

pet_bee

Lua
3
star
38

raytracer

Simple C++ raytracer
C
2
star
39

secrethitler.tv

Secret Hitler on your TV!
JavaScript
2
star
40

sybrand.ink

HTML
2
star
41

shotts

C++
2
star
42

codeart

Sass
2
star
43

elfheadedit

Small ELF file header editor
C++
2
star
44

elmscrew

An online brainfuck debugger
Elm
2
star
45

trashheap

an online """""art"""" journal whomst uploads trash
JavaScript
1
star
46

actions-eleventy-test

1
star
47

caginator-test

1
star
48

azure-keyvault-encryption-test

C++
1
star
49

actions-test

C++
1
star
50

presentation_optional_expected

CSS
1
star
51

cpp-con

C++
1
star
52

cpphalloffame

HTML
1
star
53

tartanllama.xyz

HTML
1
star
54

constraint-solver

[OLD] A constraint solver
Common Lisp
1
star