1 /*@ C++ auto_type_toolbox<T>. For the lazy sort.
2 *@ If su_A_T_T_DECL_ONLY is defined before inclusion, just enough for
3 *@ prototyping a deriviation is provided.
5 * Copyright (c) 2003 - 2019 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
6 * SPDX-License-Identifier: ISC
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #ifndef su_A_T_T_DECL_ONLY
29 * \brief Automatic \r{type_toolbox<T>} toolboxes
31 * This file has the special property that if the preprocessor variable
32 * \c{su_A_T_T_DECL_ONLY} is defined before it is included, then only minimal
33 * declarations are provided, just enough to prototype an actual usage
35 * A later inclusion (without that variable) will then provide the definitions.
40 su_USECASE_MX_DISABLED
41 #if !su_C_LANG || defined CXX_DOXYGEN
43 #ifndef su_A_T_T_DECL_ONLY
48 #include <su/code-in.h>
51 template<class T
> class auto_type_toolbox
;
53 #ifndef su_A_T_T_DECL_OK
54 # define su_A_T_T_DECL_OK
58 * \brief Automatic \r{type_toolbox<T>} toolboxes (\r{su/a-t-t.h})
60 * Supposed that a (newly created) C++ type provides a basic set of
61 * functionality, easy creation of a toolbox instance becomes possible:
64 * auto_type_toolbox<TYPE> const att;
66 * type_toolbox<TYPE> const *ttp = att.get_instance();
69 * For this to work, we need:
72 * A default constructor and an assignment method, the latter of which with the
73 * \r{su_state_err_type} plus \r{su_state_err_flags} status argument documented
74 * for \r{su_clone_fun}.
76 * An unequality operator \fn{!=}.
78 * A function \fn{uz hash(void) const}.
81 * \remarks{If \a{T} is a pointer type, the a-t-t will still create heap
82 * clones, so \c{T*} and \c{T} are in fact treated alike!}
84 * \remarks{Many \SU object types and functionality groups offer
85 * specializations, for example \r{CS}.}
88 class auto_type_toolbox
{
91 typedef NSPC(su
)type_traits
<T
> type_traits
;
93 /*! Accessing this field should be avoided because there may be
94 * specializations which do not offer it -- \r{get_instance()} is inline. */
95 static type_toolbox
<T
> const instance
;
98 static type_toolbox
<T
> const *get_instance(void) {return &instance
;}
101 static typename
type_traits::tp
s_clone(typename
type_traits::tp_const t
,
103 static void s_delete(typename
type_traits::tp self
);
104 static typename
type_traits::tp
s_assign(typename
type_traits::tp self
,
105 typename
type_traits::tp_const t
, u32 estate
);
106 static sz
s_compare(typename
type_traits::tp_const self
,
107 typename
type_traits::tp_const t
);
108 static uz
s_hash(typename
type_traits::tp_const self
);
110 #endif /* su_A_T_T_DECL_OK */
112 #ifdef su_A_T_T_DECL_ONLY
113 # undef su_A_T_T_DECL_ONLY
116 PRI STA typename
type_traits::tp
117 auto_type_toolbox
<T
>::s_clone(typename
type_traits::tp_const t
, u32 estate
){
118 ASSERT_RET(t
!= NIL
, NIL
);
119 type_traits::tp self
= su_NEW(typename
type_traits::type
);
120 if(self
->assign(t
, estate
) != 0){
129 auto_type_toolbox
<T
>::s_delete(typename
type_traits::tp self
){
130 ASSERT_RET_VOID(self
!= NIL
);
135 PRI STA typename
type_traits::tp
136 auto_type_toolbox
<T
>::s_assign(typename
type_traits::tp self
,
137 typename
type_traits::tp_const t
, u32 estate
){
138 ASSERT_RET(self
!= NIL
, NIL
);
139 ASSER_RET(t
!= NIL
, self
);
141 if(self
->assign(t
, estate
) != 0)
149 auto_type_toolbox
<T
>::s_compare(typename
type_traits::tp_const self
,
150 typename
type_traits::tp_const t
){
151 ASSERT_RET(self
!= NIL
, (t
!= NIL
) ? -1 : 0);
152 ASSERT_RET(t
!= NIL
, 1);
153 return self
->compare(*t
);
158 auto_type_toolbox
<T
>::s_hash(typename
type_traits::tp_const self
){
159 ASSERT_RET(self
!= NIL
, 0);
164 STA type_toolbox
<T
> const auto_type_toolbox
<T
>::instance
=
165 su_TYPE_TOOLBOX_I9R(&s_clone
, &s_delete
, &s_assign
, &s_compare
, &s_hash
);
166 #endif // !su_A_T_T_DECL_ONLY
169 #include <su/code-ou.h>
170 #endif /* !su_C_LANG || defined CXX_DOXYGEN */
171 #endif /* su_A_T_T_H */