libopenraw
option.hpp
1/* -*- mode: C++; tab-width: 2; c-basic-offset: 2; indent-tabs-mode:nil; -*- */
2/*
3 * libopenraw - option.hpp
4 *
5 * Copyright (C) 2017 Hubert Figuière
6 *
7 * This library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22// an option<> template class inspired by Rust
23
24#pragma once
25
26#include <stdexcept>
27
28template<class T>
29class Option
30{
31public:
32 typedef T value_type;
33
34 Option()
35 : m_none(true)
36 , m_data()
37 {
38 }
39 explicit Option(T&& data)
40 : m_none(false)
41 , m_data(data)
42 {
43 }
44 explicit Option(const T& data)
45 : m_none(false)
46 , m_data(data)
47 {
48 }
49 template<class... Args>
50 Option(Args&&... args)
51 : m_none(false)
52 , m_data(args...)
53 {
54 }
55
56 T&& value()
57 {
58 if (m_none) {
59 throw std::runtime_error("none option value");
60 }
61 m_none = true;
62 return std::move(m_data);
63 }
64 T&& value_or(T&& def)
65 {
66 if (m_none) {
67 return std::move(def);
68 }
69 m_none = true;
70 return std::move(m_data);
71 }
72
73 bool empty() const
74 { return m_none; }
75
76 constexpr explicit operator bool() const
77 { return !m_none; }
78 constexpr bool has_value() const
79 { return !m_none; }
80private:
81 bool m_none;
82 T m_data;
83};