1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef VARIANT_HXX
19#define VARIANT_HXX
20
21#include "Rect.hxx"
22#include "bspf.hxx"
23
24/**
25 This class implements a very simple variant type, which is convertible
26 to several other types. It stores the actual data as a string, and
27 converts to other types as required. Eventually, this class may be
28 extended to use templates and become a more full-featured variant type.
29
30 @author Stephen Anthony
31*/
32class Variant
33{
34 private:
35 // Underlying data store is (currently) always a string
36 string data;
37
38 // Use singleton so we use only one ostringstream object
39 inline ostringstream& buf() {
40 static ostringstream buf;
41 return buf;
42 }
43
44 public:
45 Variant() { }
46
47 Variant(const string& s) : data(s) { }
48 Variant(const char* s) : data(s) { }
49
50 Variant(Int32 i) { buf().str(""); buf() << i; data = buf().str(); }
51 Variant(uInt32 i) { buf().str(""); buf() << i; data = buf().str(); }
52 Variant(float f) { buf().str(""); buf() << f; data = buf().str(); }
53 Variant(double d) { buf().str(""); buf() << d; data = buf().str(); }
54 Variant(bool b) { buf().str(""); buf() << b; data = buf().str(); }
55 Variant(const Common::Size& s) { buf().str(""); buf() << s; data = buf().str(); }
56 Variant(const Common::Point& s) { buf().str(""); buf() << s; data = buf().str(); }
57
58 // Conversion methods
59 const string& toString() const { return data; }
60 const char* toCString() const { return data.c_str(); }
61 Int32 toInt() const {
62 istringstream ss(data);
63 Int32 parsed;
64 ss >> parsed;
65
66 return parsed;
67 }
68 float toFloat() const {
69 istringstream ss(data);
70 float parsed;
71 ss >> parsed;
72
73 return parsed;
74 }
75 bool toBool() const { return data == "1" || data == "true"; }
76 Common::Size toSize() const { return Common::Size(data); }
77 Common::Point toPoint() const { return Common::Point(data); }
78
79 // Comparison
80 bool operator==(const Variant& v) const { return data == v.data; }
81 bool operator!=(const Variant& v) const { return data != v.data; }
82
83 friend ostream& operator<<(ostream& os, const Variant& v) {
84 return os << v.data;
85 }
86};
87
88// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
89static const Variant EmptyVariant;
90
91// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
92using VariantList = vector<std::pair<string,Variant>>;
93
94namespace VarList {
95 inline void push_back(VariantList& list, const Variant& name,
96 const Variant& tag = EmptyVariant)
97 {
98 list.emplace_back(name.toString(), tag);
99 }
100}
101
102// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
103static const VariantList EmptyVarList;
104
105#endif
106