rttr  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
property_container_func.h
Go to the documentation of this file.
1 /************************************************************************************
2 * *
3 * Copyright (c) 2014 Axel Menzel <info@axelmenzel.de> *
4 * *
5 * This file is part of RTTR (Run Time Type Reflection) *
6 * License: MIT License *
7 * *
8 * Permission is hereby granted, free of charge, to any person obtaining *
9 * a copy of this software and associated documentation files (the "Software"), *
10 * to deal in the Software without restriction, including without limitation *
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
12 * and/or sell copies of the Software, and to permit persons to whom the *
13 * Software is furnished to do so, subject to the following conditions: *
14 * *
15 * The above copyright notice and this permission notice shall be included in *
16 * all copies or substantial portions of the Software. *
17 * *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
24 * SOFTWARE. *
25 * *
26 *************************************************************************************/
27 
28 #ifndef __RTTR_PROPERTY_CONTAINER_FUNC_H__
29 #define __RTTR_PROPERTY_CONTAINER_FUNC_H__
30 
33 // global function getter/setter - function pointer
34 
35 template<typename Getter, typename Setter>
36 class property_container<function_ptr, Getter, Setter, return_as_copy, set_value> : public property_container_base
37 {
38  using return_type = typename function_traits<Getter>::return_type;
39  using arg_type = typename param_types<Setter, 0>::type;
40 
41  public:
42  property_container(const std::string& name, const type declaring_type, Getter getter, Setter setter)
43  : property_container_base(name, declaring_type),
44  _getter(getter),
45  _setter(setter)
46  {
47  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-function without arguments.");
48  static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-function with exactly one argument.");
49  static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
50  }
51 
52  bool is_readonly() const { return false; }
53  bool is_static() const { return true; }
54  type get_type() const { return type::get<return_type>(); }
55  bool is_array() const { return detail::is_array<return_type>::value; }
56 
57  bool set_value(detail::instance& object, detail::argument& arg) const
58  {
59  if (arg.is_type<arg_type>())
60  {
61  _setter(arg.get_value<arg_type>());
62  return true;
63  }
64  return false;
65  }
66 
67  variant get_value(detail::instance& object) const
68  {
69  return variant(_getter());
70  }
71 
72  private:
73  Getter _getter;
74  Setter _setter;
75 };
76 
79 // global function getter
80 
81 template<typename Getter>
82 class property_container<function_ptr, Getter, void, return_as_copy, read_only> : public property_container_base
83 {
84  using return_type = typename function_traits<Getter>::return_type;
85 
86  public:
87  property_container(const std::string& name, const type declaring_type, Getter func)
88  : property_container_base(name, declaring_type),
89  _accessor(func)
90  {
91  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-function without arguments.");
92  }
93 
94  bool is_readonly() const { return true; }
95  bool is_static() const { return true; }
96  type get_type() const { return type::get<return_type>(); }
97  bool is_array() const { return detail::is_array<return_type>::value; }
98 
99  bool set_value(detail::instance& object, detail::argument& arg) const
100  {
101  return false;
102  }
103 
104  variant get_value(detail::instance& object) const
105  {
106  return (variant(_accessor()));
107  }
108 
109  private:
110  Getter _accessor;
111 };
112 
113 
114 
117 // global function getter/setter
118 
119 template<typename Getter, typename Setter>
120 class property_container<function_ptr, Getter, Setter, return_as_ptr, set_as_ptr> : public property_container_base
121 {
122  using return_type = typename function_traits<Getter>::return_type;
123  using arg_type = typename param_types<Setter, 0>::type;
124 
125  public:
126  property_container(const std::string& name, const type declaring_type, Getter getter, Setter setter)
127  : property_container_base(name, declaring_type),
128  _getter(getter),
129  _setter(setter)
130  {
131  static_assert(std::is_reference<return_type>::value, "Please provide a getter-function with a reference as return value!");
132  static_assert(std::is_reference<arg_type>::value, "Please provide a setter-function with a reference as argument!");
133 
134  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-function without arguments.");
135  static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-function with exactly one argument.");
136 
137  static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
138  }
139 
140  bool is_readonly() const { return false; }
141  bool is_static() const { return true; }
142  type get_type() const { return type::get<typename std::remove_reference<return_type>::type*>(); }
143  bool is_array() const { return detail::is_array<return_type>::value; }
144 
145  bool set_value(detail::instance& object, detail::argument& arg) const
146  {
147  using arg_type = typename std::remove_reference<arg_type>::type;
148  if (arg.is_type<arg_type*>())
149  {
150  _setter(*arg.get_value<arg_type*>());
151  return true;
152  }
153  return false;
154  }
155 
156  variant get_value(detail::instance& object) const
157  {
158  return variant(&(_getter()));
159  }
160 
161  private:
162  Getter _getter;
163  Setter _setter;
164 };
165 
168 // global function getter
169 
170 template<typename Getter>
171 class property_container<function_ptr, Getter, void, return_as_ptr, read_only> : public property_container_base
172 {
173  using return_type = typename function_traits<Getter>::return_type;
174  public:
175  property_container(const std::string& name, const type declaring_type, Getter func)
176  : property_container_base(name, declaring_type),
177  _accessor(func)
178  {
179  static_assert(std::is_reference<return_type>::value, "Please provide a function with a reference as return value!");
180  }
181 
182  bool is_readonly() const { return true; }
183  bool is_static() const { return true; }
184  type get_type() const { return type::get<typename std::add_const<typename std::remove_reference<return_type>::type>::type*>(); }
185  bool is_array() const { return detail::is_array<return_type>::value; }
186 
187  bool set_value(detail::instance& object, detail::argument& arg) const
188  {
189  return false;
190  }
191 
192  variant get_value(detail::instance& object) const
193  {
194  return (variant(const_cast<const typename std::remove_reference<return_type>::type*>(&(_accessor()))));
195  }
196 
197  private:
198  Getter _accessor;
199 };
200 
201 
202 #endif // __RTTR_PROPERTY_CONTAINER_FUNC_H__