8 #include <eet_register.hh>
10 #include <type_traits>
17 namespace efl { namespace eet { namespace _detail {
20 void* _allocate( ::size_t size )
22 assert(size == sizeof(T));
28 void _deallocate( void* p )
30 delete static_cast<T*>(p);
33 template <typename T, typename... Args>
34 struct descriptor_type
38 template <typename A, typename B>
39 struct apply : _mpl::push_back<A, typename _detail::member_type<typename B::member_type>::type> {};
42 typedef typename _mpl::fold< std::tuple<Args...>, push_back
43 , descriptor<T> >::type type;
48 #define EET_CXX_MEMBER(C, I) ::efl::eet::type(#I, &C::I)
51 _detail::member_info<F, void> type(const char* name, F f)
53 typedef typename _detail::member_type<F>::type member_type;
54 static_assert(is_eet_primitive<member_type>::value, "");
55 static_assert(std::is_member_pointer<F>::value, "");
56 return _detail::member_info<F, void>{name, f};
59 template <typename F, typename U, typename... Args>
60 _detail::member_info<F, U, Args...> type(const char* name, F f, descriptor<U, Args...> const& descriptor)
62 typedef typename _detail::member_type<F>::type member_type;
63 static_assert(!is_eet_primitive<member_type>::value, "");
64 static_assert(std::is_member_pointer<F>::value, "");
65 return _detail::member_info<F, U, Args...>{name, f, &descriptor};
80 template <typename T, typename... Args>
83 typedef T object_type;
85 descriptor() : _descriptor(nullptr) {}
86 descriptor( ::Eet_Data_Descriptor* descriptor
87 , std::array<_detail::member_desc_info, sizeof...(Args)> member_info)
88 : _descriptor(descriptor), _member_info(member_info)
91 descriptor(descriptor&& other)
92 : _descriptor(other._descriptor)
94 other._descriptor = 0;
96 descriptor& operator=(descriptor&& other)
99 eet_data_descriptor_free(_descriptor);
100 _descriptor = other._descriptor;
101 other._descriptor = 0;
107 eet_data_descriptor_free(_descriptor);
109 typedef ::Eet_Data_Descriptor const* const_native_handle_type;
110 typedef ::Eet_Data_Descriptor* native_handle_type;
111 const_native_handle_type native_handle() const
115 native_handle_type native_handle()
119 typedef std::integral_constant<std::size_t, sizeof...(Args)> members;
121 std::array<_detail::member_desc_info, sizeof...(Args)> get_member_info() const { return _member_info; }
123 ::Eet_Data_Descriptor* _descriptor;
124 typedef descriptor<T, Args...> _self_type;
125 descriptor(descriptor const&) = delete;
126 descriptor& operator=(descriptor const&) = delete;
127 std::array<_detail::member_desc_info, sizeof...(Args)> _member_info;
130 template <typename T, typename... Args>
131 std::unique_ptr<T> read_by_ptr(Eet_File* file, const char* name, descriptor<T, Args...> const& d)
133 void* p = eet_data_read(file, const_cast<descriptor<T, Args...>&>(d).native_handle(), name);
134 return std::unique_ptr<T>(static_cast<T*>(p));
137 template <typename T, typename... Args>
138 T read(Eet_File* file, const char* name, descriptor<T, Args...> const& d)
140 typename std::aligned_storage<sizeof(T), alignof(T)>::type buffer;
142 ::eet_data_read_cipher_buffer
144 , const_cast<descriptor<T, Args...>&>(d).native_handle()
146 , static_cast<char*>(static_cast<void*>(&buffer))
150 assert(p == &buffer);
151 return *static_cast<T*>(p);
154 throw std::runtime_error("");
159 template <typename O>
160 inline void _item_fill(O*, ::Eet_Data_Descriptor*, member_desc_info*) {}
162 template <typename O, typename F, typename D, typename... Args, typename... FArgs>
163 inline void _item_fill(O* obj, ::Eet_Data_Descriptor* cls, member_desc_info* offset
164 , _detail::member_info<F, D, Args...> arg0, FArgs... args)
166 static_assert(std::is_member_object_pointer<F>::value, "");
167 offset->offset = static_cast<char*>( static_cast<void*>( &(obj ->* arg0.member) ))
168 - static_cast<char*>( static_cast<void*>( obj ) );
169 offset->name = arg0.name;
170 _detail::_item_fill(obj, cls, ++offset, args...);
175 template <typename F, typename D, typename... OArgs, typename... Args>
176 typename _detail::descriptor_type
177 <typename _detail::object_type<F>::type
178 , _detail::member_info<F, D, OArgs...>, Args...
179 >::type make_descriptor(const char* name, _detail::member_info<F, D, OArgs...> a0, Args... args)
181 typedef F member_pointer;
182 static_assert(std::is_member_object_pointer<member_pointer>::value, "");
183 typedef typename _detail::object_type<member_pointer>::type object_type;
185 typedef typename _detail::descriptor_type
186 <object_type, _detail::member_info<F, D, OArgs...>, Args...>::type descriptor_type;
188 ::Eet_Data_Descriptor_Class cls
190 EET_DATA_DESCRIPTOR_CLASS_VERSION
192 , sizeof(object_type)
194 & _detail::_allocate<object_type>
195 , & _detail::_deallocate<object_type>
198 ::Eet_Data_Descriptor* native_handle = eet_data_descriptor_stream_new(&cls);
200 throw std::runtime_error("");
202 typename std::aligned_storage<sizeof(object_type), alignof(object_type)>::type buffer;
203 object_type* p = static_cast<object_type*>(static_cast<void*>(&buffer));
205 std::array<_detail::member_desc_info, sizeof...(Args)+1> offsets;
206 _detail::_item_fill(p, native_handle, &offsets[0], a0, args...);
207 _detail::descriptor_type_register(native_handle, &offsets[0], a0, args...);
209 return descriptor_type(native_handle, offsets);