1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 3 4 /* 5 Rosegarden 6 A sequencer and musical notation editor. 7 Copyright 2000-2021 the Rosegarden development team. 8 See the AUTHORS file for more details. 9 10 This program is free software; you can redistribute it and/or 11 modify it under the terms of the GNU General Public License as 12 published by the Free Software Foundation; either version 2 of the 13 License, or (at your option) any later version. See the file 14 COPYING included with this distribution for more information. 15 */ 16 17 #ifndef RG_PROPERTY_H 18 #define RG_PROPERTY_H 19 20 #include "RealTime.h" 21 22 #include <QDebug> 23 24 #include <string> 25 26 #include <rosegardenprivate_export.h> 27 28 namespace Rosegarden 29 { 30 31 enum PropertyType { Int, String, Bool, RealTimeT }; 32 33 template <PropertyType P> 34 class ROSEGARDENPRIVATE_EXPORT PropertyDefn 35 { 36 public: 37 struct PropertyDefnNotDefined { PropertyDefnNotDefinedPropertyDefnNotDefined38 PropertyDefnNotDefined() { throw(0); } 39 }; 40 typedef PropertyDefnNotDefined basic_type; 41 typeName()42 static std::string typeName() { return "Undefined"; } 43 static basic_type parse(std::string); 44 static std::string unparse(basic_type); 45 }; 46 47 template <PropertyType P> 48 typename PropertyDefn<P>::basic_type parse(std::string)49PropertyDefn<P>::parse(std::string) 50 { 51 throw(0); 52 return ""; 53 } 54 55 template <PropertyType P> 56 std::string unparse(typename PropertyDefn<P>::basic_type)57PropertyDefn<P>::unparse(typename PropertyDefn<P>::basic_type) 58 { 59 throw(0); 60 return ""; 61 } 62 63 64 template <> 65 class PropertyDefn<Int> 66 { 67 public: 68 typedef long basic_type; 69 70 static std::string typeName(); 71 static basic_type parse(std::string s); 72 static std::string unparse(basic_type i); 73 }; 74 75 76 template <> 77 class PropertyDefn<String> 78 { 79 public: 80 typedef std::string basic_type; 81 82 static std::string typeName(); 83 static basic_type parse(std::string s); 84 static std::string unparse(basic_type i); 85 }; 86 87 template <> 88 class PropertyDefn<Bool> 89 { 90 public: 91 typedef bool basic_type; 92 93 static std::string typeName(); 94 static basic_type parse(std::string s); 95 static std::string unparse(basic_type i); 96 }; 97 98 template <> 99 class PropertyDefn<RealTimeT> 100 { 101 public: 102 typedef RealTime basic_type; 103 104 static std::string typeName(); 105 static basic_type parse(std::string s); 106 static std::string unparse(basic_type i); 107 }; 108 109 110 class ROSEGARDENPRIVATE_EXPORT PropertyStoreBase { 111 public: 112 virtual ~PropertyStoreBase(); 113 114 virtual PropertyType getType() const = 0; 115 virtual std::string getTypeName() const = 0; 116 virtual PropertyStoreBase *clone() = 0; 117 virtual std::string unparse() const = 0; 118 119 virtual size_t getStorageSize() const = 0; // for debugging 120 121 #ifndef NDEBUG 122 virtual void dump(std::ostream&) const = 0; 123 #else dump(std::ostream &)124 virtual void dump(std::ostream&) const { } 125 #endif 126 }; 127 128 #ifndef NDEBUG 129 inline std::ostream& operator<<(std::ostream &out, PropertyStoreBase &e) 130 { e.dump(out); return out; } 131 #endif 132 133 inline QDebug &operator<<(QDebug &dbg, const PropertyStoreBase &psb) 134 { 135 dbg << psb.getTypeName().c_str() << "-" << psb.unparse().c_str(); 136 return dbg; 137 } 138 139 template <PropertyType P> 140 class ROSEGARDENPRIVATE_EXPORT PropertyStore : public PropertyStoreBase 141 { 142 public: PropertyStore(typename PropertyDefn<P>::basic_type d)143 PropertyStore(typename PropertyDefn<P>::basic_type d) : 144 m_data(d) { } PropertyStore(const PropertyStore<P> & p)145 PropertyStore(const PropertyStore<P> &p) : 146 PropertyStoreBase(p), m_data(p.m_data) { } 147 PropertyStore &operator=(const PropertyStore<P> &p); 148 149 PropertyType getType() const override; 150 std::string getTypeName() const override; 151 152 PropertyStoreBase* clone() override; 153 154 std::string unparse() const override; 155 getData()156 typename PropertyDefn<P>::basic_type getData() { return m_data; } setData(typename PropertyDefn<P>::basic_type data)157 void setData(typename PropertyDefn<P>::basic_type data) { m_data = data; } 158 159 size_t getStorageSize() const override; 160 161 #ifndef NDEBUG 162 void dump(std::ostream&) const override; 163 #endif 164 165 private: 166 typename PropertyDefn<P>::basic_type m_data; 167 }; 168 169 template <PropertyType P> 170 PropertyStore<P>& 171 PropertyStore<P>::operator=(const PropertyStore<P> &p) { 172 if (this != &p) { 173 m_data = p.m_data; 174 } 175 return *this; 176 } 177 178 template <PropertyType P> 179 PropertyType getType()180PropertyStore<P>::getType() const 181 { 182 return P; 183 } 184 185 template <PropertyType P> 186 std::string getTypeName()187PropertyStore<P>::getTypeName() const 188 { 189 return PropertyDefn<P>::typeName(); 190 } 191 192 template <PropertyType P> 193 PropertyStoreBase* clone()194PropertyStore<P>::clone() 195 { 196 return new PropertyStore<P>(*this); 197 } 198 199 template <PropertyType P> 200 std::string unparse()201PropertyStore<P>::unparse() const 202 { 203 return PropertyDefn<P>::unparse(m_data); 204 } 205 206 #ifndef NDEBUG 207 template <PropertyType P> 208 void dump(std::ostream & out)209PropertyStore<P>::dump(std::ostream &out) const 210 { 211 out << getTypeName() << " - " << unparse(); 212 } 213 #endif 214 215 } 216 217 218 #endif 219