neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
custom_type.hpp
Go to the documentation of this file.
1// custom_type.hpp
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <any>
40#include <optional>
45
46namespace neolib
47{
48 template <typename T>
49 class custom_type : public reference_counted<i_custom_type>
50 {
51 public:
52 struct type_mismatch : std::logic_error { type_mismatch() : std::logic_error("neolib::custom_type::type_mismatch") {} };
53 private:
54 typedef T value_type;
55 typedef abstract_t<value_type> abstract_value_type;
56 typedef std::optional<value_type> container_type;
57 public:
58 custom_type(const string& aName) :
59 iName{ aName } {}
60 custom_type(const string& aName, const string& aValue) :
61 iName{ aName }, iInstance{ from_string<T>(aValue) } {}
62 custom_type(const string& aName, const abstract_value_type& aValue) :
63 iName{ aName }, iInstance{ aValue } {}
64 custom_type(const i_custom_type& aOther) :
65 iName{ aOther.name() }, iInstance{ aOther.instance_ptr() ? container_type{aOther.instance_as<abstract_value_type>()} : container_type{} } {}
67 public:
70 void name(i_string& aName) const final
71 {
72 aName = iName;
73 }
74 void to_string(i_string& aString) const final
75 {
76 if (!!iInstance)
77 aString = to_string(*iInstance);
78 else
79 aString.clear();
80 }
81 i_custom_type* clone() const final
82 {
83 return new custom_type{ *this };
84 }
86 {
87 if (aRhs.name() != name())
88 throw type_mismatch();
89 if (iInstance == std::nullopt)
90 iInstance = value_type{ aRhs.instance_as<abstract_value_type>() };
91 else
92 *iInstance = aRhs.instance_as<abstract_value_type>();
93 return *this;
94 }
95 bool operator==(const i_custom_type& aRhs) const final
96 {
97 return instance_ptr() == aRhs.instance_ptr() || (instance_ptr() != nullptr && aRhs.instance_ptr() != nullptr && instance_as<abstract_value_type>() == aRhs.instance_as<abstract_value_type>());
98 }
99 bool operator<(const i_custom_type& aRhs) const final
100 {
101 return (instance_ptr() != nullptr && aRhs.instance_ptr() != nullptr && instance_as<abstract_value_type>() < aRhs.instance_as<abstract_value_type>()) || (instance_ptr() < aRhs.instance_ptr());
102 }
103 public:
104 const void* instance_ptr() const final
105 {
106 return iInstance != std::nullopt ? static_cast<const abstract_value_type*>(&*iInstance) : static_cast<const abstract_value_type*>(nullptr);
107 }
108 void* instance_ptr() final
109 {
110 return iInstance != std::nullopt ? static_cast<abstract_value_type*>(&*iInstance) : static_cast<abstract_value_type*>(nullptr);
111 }
112 private:
113 string iName;
114 container_type iInstance;
115 };
116
117 template <typename T>
118 const std::string custom_type_name_v = T::type_name;
119
120 template <typename T>
122 {
123 return custom_type<T>{ custom_type_name_v<T> };
124 }
125
126 template <typename T>
128 {
129 return custom_type<T>{ custom_type_name_v<T>, aValue };
130 }
131}
void * instance_ptr() final
void to_string(i_string &aString) const final
bool operator==(const i_custom_type &aRhs) const final
void name(i_string &aName) const final
const void * instance_ptr() const final
std::string name() const
i_custom_type & assign(const i_custom_type &aRhs) final
i_custom_type * clone() const final
custom_type(const i_custom_type &aOther)
custom_type(const string &aName, const abstract_value_type &aValue)
bool operator<(const i_custom_type &aRhs) const final
std::string to_string() const
custom_type(const string &aName)
custom_type(const string &aName, const string &aValue)
const T & instance_as() const
std::string name() const
std::string to_string() const
typename detail::abstract_type< T >::type abstract_t
Definition neolib.hpp:178
const std::string custom_type_name_v
T from_string(i_string const &aValueAsString)
custom_type< T > make_custom_type()