Bump S-nail v14.9.16 ("Message of Winter, your hopes shall be crushed"), 2019-12-29
[s-mailx.git] / include / su / a-t-t.h
blob8c060e5ebbfe861e923aad3bda934810c1221416
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.
20 #ifndef su_A_T_T_H
21 #ifndef su_A_T_T_DECL_ONLY
22 # define su_A_T_T_H
23 #endif
25 #ifdef CXX_DOXYGEN
26 /*!
27 * \file
28 * \ingroup COLL
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
34 * \c{typedef}.
35 * A later inclusion (without that variable) will then provide the definitions.
37 #endif
39 #include <su/code.h>
40 su_USECASE_MX_DISABLED
41 #if !su_C_LANG || defined CXX_DOXYGEN
43 #ifndef su_A_T_T_DECL_ONLY
44 # include <su/mem.h>
45 #endif
47 #define su_CXX_HEADER
48 #include <su/code-in.h>
49 NSPC_BEGIN(su)
51 template<class T> class auto_type_toolbox;
53 #ifndef su_A_T_T_DECL_OK
54 # define su_A_T_T_DECL_OK
56 /*!
57 * \ingroup COLL
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:
63 * \cb{
64 * auto_type_toolbox<TYPE> const att;
66 * type_toolbox<TYPE> const *ttp = att.get_instance();
67 * }
69 * For this to work, we need:
71 * \list{\li{
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}.
75 * }\li{
76 * An unequality operator \fn{!=}.
77 * }\li{
78 * A function \fn{uz hash(void) const}.
79 * }}
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}.}
87 template<class T>
88 class auto_type_toolbox{
89 public:
90 /*! \_ */
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;
97 /*! \_ */
98 static type_toolbox<T> const *get_instance(void) {return &instance;}
100 private:
101 static typename type_traits::tp s_clone(typename type_traits::tp_const t,
102 u32 estate);
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
114 #else
115 template<class T>
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){
121 su_DEL(self);
122 self = NIL;
124 return self;
127 template<class T>
128 PRI STA void
129 auto_type_toolbox<T>::s_delete(typename type_traits::tp self){
130 ASSERT_RET_VOID(self != NIL);
131 su_DEL(self);
134 template<class T>
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);
140 if(self != t){
141 if(self->assign(t, estate) != 0)
142 self = NIL;
144 return self;
147 template<class T>
148 PRI STA sz
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);
156 template<class T>
157 PRI STA uz
158 auto_type_toolbox<T>::s_hash(typename type_traits::tp_const self){
159 ASSERT_RET(self != NIL, 0);
160 return self->hash();
163 template<class T>
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
168 NSPC_END(su)
169 #include <su/code-ou.h>
170 #endif /* !su_C_LANG || defined CXX_DOXYGEN */
171 #endif /* su_A_T_T_H */
172 /* s-it-mode */