rttr  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
property_container_member_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_MEMBER_FUNC_H__
29 #define __RTTR_PROPERTY_CONTAINER_MEMBER_FUNC_H__
30 
33 // Getter/Setter - pointer to member function
34 
35 template<typename Getter, typename Setter>
36 class property_container<member_func_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  using class_type = typename function_traits<Getter>::class_type;
41 
42  public:
43  property_container(const std::string& name, const type declaring_type, Getter get, Setter set)
44  : property_container_base(name, declaring_type),
45  _getter(get),
46  _setter(set)
47  {
48  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
49  static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-member-function with exactly one argument.");
50  static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
51  }
52 
53  bool is_readonly() const { return false; }
54  bool is_static() const { return false; }
55  type get_type() const { return type::get<return_type>(); }
56  bool is_array() const { return detail::is_array<return_type>::value; }
57 
58  bool set_value(detail::instance& object, detail::argument& arg) const
59  {
60  class_type* ptr = object.try_convert<class_type>();
61  if (ptr && arg.is_type<arg_type>() )
62  {
63  (ptr->*_setter)(arg.get_value<arg_type>());
64  return true;
65  }
66  return false;
67  }
68 
69  variant get_value(detail::instance& object) const
70  {
71  if (class_type* ptr = object.try_convert<class_type>())
72  return variant((ptr->*_getter)());
73  else
74  return variant();
75  }
76 
77  private:
78  Getter _getter;
79  Setter _setter;
80 };
81 
84 // Getter - pointer to member function
85 
86 template<typename Getter>
87 class property_container<member_func_ptr, Getter, void, return_as_copy, read_only> : public property_container_base
88 {
89  using return_type = typename function_traits<Getter>::return_type;
90  using class_type = typename function_traits<Getter>::class_type;
91 
92  public:
93  property_container(const std::string& name, const type declaring_type, Getter get)
94  : property_container_base(name, declaring_type),
95  _getter(get)
96  {
97  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
98  }
99 
100  bool is_readonly() const { return false; }
101  bool is_static() const { return false; }
102  type get_type() const { return type::get<return_type>(); }
103  bool is_array() const { return detail::is_array<return_type>::value; }
104 
105  bool set_value(detail::instance& object, detail::argument& arg) const
106  {
107  return false;
108  }
109 
110  variant get_value(detail::instance& object) const
111  {
112  if (class_type* ptr = object.try_convert<class_type>())
113  return variant((ptr->*_getter)());
114  else
115  return variant();
116  }
117 
118  private:
119  Getter _getter;
120 };
121 
123 // Policy return_as_ptr
125 
126 // Getter/Setter pointer to member function
127 template<typename Getter, typename Setter>
128 class property_container<member_func_ptr, Getter, Setter, return_as_ptr, set_as_ptr> : public property_container_base
129 {
130  using return_type = typename function_traits<Getter>::return_type;
131  using arg_type = typename param_types<Setter, 0>::type;
132  using class_type = typename function_traits<Getter>::class_type;
133 
134  public:
135  property_container(const std::string& name, const type declaring_type, Getter get, Setter set)
136  : property_container_base(name, declaring_type),
137  _getter(get),
138  _setter(set)
139  {
140  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
141  static_assert(function_traits<Setter>::arg_count == 1, "Invalid number of argument, please provide a setter-member-function with exactly one argument.");
142  static_assert(std::is_same<return_type, arg_type>::value, "Please provide the same signature for getter and setter!");
143 
144  static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
145  static_assert(std::is_reference<arg_type>::value, "Please provide a setter-member-function with a reference as return value!");
146  }
147 
148  bool is_readonly() const { return false; }
149  bool is_static() const { return false; }
150  type get_type() const { return type::get<typename std::remove_reference<return_type>::type*>(); }
151  bool is_array() const { return detail::is_array<return_type>::value; }
152 
153  bool set_value(detail::instance& object, detail::argument& arg) const
154  {
155  using arg_type = typename std::remove_reference<arg_type>::type;
156  class_type* ptr = object.try_convert<class_type>();
157  if (ptr && arg.is_type<arg_type*>())
158  {
159  (ptr->*_setter)(*arg.get_value<arg_type*>());
160  return true;
161  }
162  return false;
163  }
164 
165  variant get_value(detail::instance& object) const
166  {
167  if (class_type* ptr = object.try_convert<class_type>())
168  return variant(&(ptr->*_getter)());
169  else
170  return variant();
171  }
172 
173  private:
174  Getter _getter;
175  Setter _setter;
176 
177 };
178 
181 // Getter - pointer to member function
182 
183 template<typename Getter>
184 class property_container<member_func_ptr, Getter, void, return_as_ptr, read_only> : public property_container_base
185 {
186  using return_type = typename function_traits<Getter>::return_type;
187  using class_type = typename function_traits<Getter>::class_type;
188 
189  public:
190  property_container(const std::string& name, const type declaring_type, Getter get)
191  : property_container_base(name, declaring_type),
192  _getter(get)
193  {
194  static_assert(function_traits<Getter>::arg_count == 0, "Invalid number of argument, please provide a getter-member-function without arguments.");
195  static_assert(std::is_reference<return_type>::value, "Please provide a getter-member-function with a reference as return value!");
196  }
197 
198  bool is_readonly() const { return true; }
199  bool is_static() const { return false; }
200  type get_type() const { return type::get<typename std::remove_reference<return_type>::type*>(); }
201  bool is_array() const { return detail::is_array<return_type>::value; }
202 
203  bool set_value(detail::instance& object, detail::argument& arg) const
204  {
205  return false;
206  }
207 
208  variant get_value(detail::instance& object) const
209  {
210  if (class_type* ptr = object.try_convert<class_type>())
211  return variant(&(ptr->*_getter)());
212  else
213  return variant();
214  }
215 
216  private:
217  Getter _getter;
218 };
219 
220 #endif // __RTTR_PROPERTY_CONTAINER_MEMBER_FUNC_H__