File: Value.h

package info (click to toggle)
freespace2 24.2.0%2Brepack-3
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,740 kB
  • sloc: cpp: 595,005; ansic: 21,741; python: 1,174; sh: 457; makefile: 243; xml: 181
file content (104 lines) | stat: -rw-r--r-- 2,050 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#pragma once

#include "globalincs/pstypes.h"

#include <mpark/variant.hpp>

namespace actions {
namespace expression {

namespace detail {
template <typename ToType>
struct implicit_conversion {
	template <typename T>
	ToType operator()(const T&)
	{
		throw std::runtime_error("Invalid implicit conversion.");
	}
};

template<>
struct implicit_conversion<float> {
	inline float operator()(int val) {
		return i2fl(val);
	}

	template <typename T>
	float operator()(const T&)
	{
		throw std::runtime_error("Invalid implicit conversion.");
	}
};

} // namespace detail

enum class ValueType
{
	Invalid,
	Integer,
	Float,
	Vector,
	String,
};

template <typename T>
struct ValueTypeTraits;

template <>
struct ValueTypeTraits<int> {
	static constexpr ValueType type = ValueType::Integer;
};
template <>
struct ValueTypeTraits<float> {
	static constexpr ValueType type = ValueType::Float;
};
template <>
struct ValueTypeTraits<vec3d> {
	static constexpr ValueType type = ValueType::Vector;
};
template <>
struct ValueTypeTraits<SCP_string> {
	static constexpr ValueType type = ValueType::String;
};

class Value {
  public:
	Value() = default;

	explicit Value(int val);
	explicit Value(float val);
	explicit Value(const vec3d& val);
	explicit Value(SCP_string val);

	ValueType getType() const;

	int getInteger() const;
	float getFloat() const;
	vec3d getVector() const;
	SCP_string getIdentifier() const;

	template <typename T>
	T get() const
	{
		const auto currentType = getType();
		const auto expectedType = ValueTypeTraits<T>::type;

		if (currentType == expectedType) {
			// No conversion necessary
			return mpark::get<T>(m_value);
		}

		return mpark::visit(detail::implicit_conversion<T>{}, m_value);
	}

	friend bool operator==(const Value& lhs, const Value& rhs);
	friend bool operator!=(const Value& lhs, const Value& rhs);

	friend std::ostream& operator<<(std::ostream& os, const Value& value);

  private:
	mpark::variant<mpark::monostate, int, float, vec3d, SCP_string> m_value;
};

} // namespace expression
} // namespace actions