libopenraw
option.hpp
1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; 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 
28 template<class T>
29 class Option
30 {
31 public:
32  typedef T data_type;
33 
34  Option()
35  : m_none(true)
36  , m_data()
37  {
38  }
39  Option(T&& data)
40  : m_none(false)
41  , m_data(data)
42  {
43  }
44  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&& unwrap()
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&& unwrap_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  bool empty() const
73  { return m_none; }
74  bool ok() const
75  { return !m_none; }
76 private:
77  bool m_none;
78  T m_data;
79 };