1 /*************************************************************************** 2 * * 3 * LinuxSampler - modular, streaming capable sampler * 4 * * 5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * 6 * Copyright (C) 2005 - 2019 Christian Schoenebeck * 7 * * 8 * This program is free software; you can redistribute it and/or modify * 9 * it under the terms of the GNU General Public License as published by * 10 * the Free Software Foundation; either version 2 of the License, or * 11 * (at your option) any later version. * 12 * * 13 * This program is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 * GNU General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU General Public License * 19 * along with this program; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 21 * MA 02111-1307 USA * 22 ***************************************************************************/ 23 24 #ifndef __LS_OPTIONAL_H__ 25 #define __LS_OPTIONAL_H__ 26 27 #include "Exception.h" 28 29 namespace LinuxSampler { 30 31 /** 32 * Base class of template class optional, not meant to be instantiated 33 * directly. It just provides the optional<T>::nothing member. 34 */ 35 class optional_base { 36 public: nothing_t()37 class nothing_t { public: nothing_t() {} }; 38 39 static const nothing_t nothing; 40 }; 41 42 /** 43 * This class can be used for any variable that might not have a value 44 * set. E.g. as a return value type of a function, since in the case of 45 * return values of functions it's often difficult to return a pointer 46 * variable which might do the trick of an optional return value. It 47 * behaves pretty much like a pointer though. That is, it can be checked 48 * against NULL and the actual value can be dereferenced with the 49 * typical C pointer dereference operators. 50 */ 51 template<class T> 52 class optional : public optional_base { 53 public: optional()54 optional() { 55 initialized = false; 56 } 57 optional(T data)58 optional(T data) { 59 this->data = data; 60 initialized = true; 61 } 62 optional(nothing_t)63 optional(nothing_t) { 64 initialized = false; 65 } 66 67 template <class T_inner> optional(T_inner data)68 optional(T_inner data) { 69 this->data = T(data); 70 initialized = true; 71 } 72 get()73 const T& get() const throw (Exception) { 74 if (!initialized) throw Exception("optional variable not initialized"); 75 return data; 76 } 77 get()78 T& get() throw (Exception) { 79 if (!initialized) throw Exception("optional variable not initialized"); 80 return data; 81 } 82 83 optional& operator =(const optional& arg) { 84 this->data = arg.data; 85 initialized = arg.initialized; 86 return *this; 87 } 88 89 optional& operator =(const T& arg) { 90 this->data = arg; 91 initialized = true; 92 return *this; 93 } 94 95 bool operator ==(const optional& o) const { 96 if (!initialized || !o.initialized) 97 return initialized == o.initialized; 98 return data == o.data; 99 } 100 101 bool operator !=(const optional& o) const { 102 return !(*this == o); 103 } 104 throw(Exception)105 const T& operator *() const throw (Exception) { return get(); } throw(Exception)106 T& operator *() throw (Exception) { return get(); } 107 108 const T* operator ->() const throw (Exception) { 109 if (!initialized) throw Exception("optional variable not initialized"); 110 return &data; 111 } 112 113 T* operator ->() throw (Exception) { 114 if (!initialized) throw Exception("optional variable not initialized"); 115 return &data; 116 } 117 118 operator bool() const { return initialized; } 119 bool operator !() const { return !initialized; } 120 121 protected: 122 T data; 123 bool initialized; 124 }; 125 126 } // namespace LinuxSampler 127 128 #endif // __LS_OPTIONAL_H__ 129