libopenraw  0.3.7
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 // @file an option<> template class inspired by Rust
23 
24 #pragma once
25 
26 #include <stdexcept>
27 
41 class OptionNone {
42 };
43 
45 template<class T>
46 class Option
47 {
48 public:
49  typedef T value_type;
50 
51  Option()
52  : m_none(true)
53  , m_data()
54  {
55  }
57  : m_none(true)
58  , m_data()
59  {
60  }
61  explicit Option(T&& data)
62  : m_none(false)
63  , m_data(std::move(data))
64  {
65  }
66  explicit Option(const T& data)
67  : m_none(false)
68  , m_data(data)
69  {
70  }
71  template<class... Args>
72  Option(Args&&... args)
73  : m_none(false)
74  , m_data(args...)
75  {
76  }
77 
78  T&& value()
79  {
80  if (m_none) {
81  throw std::runtime_error("none option value");
82  }
83  m_none = true;
84  return std::move(m_data);
85  }
86  const T& value_ref() const
87  {
88  if (m_none) {
89  throw std::runtime_error("none option value");
90  }
91  return m_data;
92  }
93  T&& value_or(T&& def)
94  {
95  if (m_none) {
96  return std::move(def);
97  }
98  m_none = true;
99  return std::move(m_data);
100  }
101 
102  T& operator*()
103  {
104  if (m_none) {
105  throw std::runtime_error("none option value");
106  }
107  return m_data;
108  }
109  const T& operator*() const
110  {
111  if (m_none) {
112  throw std::runtime_error("none option value");
113  }
114  return m_data;
115  }
116 
117  bool empty() const
118  { return m_none; }
119 
120  constexpr explicit operator bool() const
121  { return !m_none; }
122  constexpr bool has_value() const
123  { return !m_none; }
124 private:
125  bool m_none;
126  T m_data;
127 };
128 
130 template<class T> Option<T>
131 option_some(T&& value)
132 {
133  return Option<T>(std::move(value));
134 }
135 
Tag class to help create an empty Option.
Definition: option.hpp:41
An option type inspired by Rust.
Definition: option.hpp:47
Option< T > option_some(T &&value)
Create an Option<T> is some value.
Definition: option.hpp:131