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.
4  *
5  * Copyright (c) 2003 - 2020 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
6  * SPDX-License-Identifier: ISC
7  *
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.
11  *
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.
19  */
20 #ifndef su_A_T_T_H
21 #ifndef su_A_T_T_DECL_ONLY
22 # define su_A_T_T_H
23 #endif
24 #ifndef su_A_T_T_DECL_ONLY
25 # include <su/mem.h>
26 #endif
27 #define su_CXX_HEADER
28 #include <su/code-in.h>
29 NSPC_BEGIN(su)
30 template<class T> class auto_type_toolbox;
31 #ifndef su_A_T_T_DECL_OK
32 # define su_A_T_T_DECL_OK
33 template<class T>
34 class auto_type_toolbox{
35 public:
36    typedef NSPC(su)type_traits<T> type_traits;
37    static type_toolbox<T> const instance;
get_instance(void)38    static type_toolbox<T> const *get_instance(void) {return &instance;}
39 private:
40    static typename type_traits::tp s_clone(typename type_traits::tp_const t,
41          u32 estate);
42    static void s_delete(typename type_traits::tp self);
43    static typename type_traits::tp s_assign(typename type_traits::tp self,
44          typename type_traits::tp_const t, u32 estate);
45    static sz s_compare(typename type_traits::tp_const self,
46          typename type_traits::tp_const t);
47    static uz s_hash(typename type_traits::tp_const self);
48 };
49 #endif /* su_A_T_T_DECL_OK */
50 #ifdef su_A_T_T_DECL_ONLY
51 # undef su_A_T_T_DECL_ONLY
52 #else
53 template<class T>
54 PRI STA typename type_traits::tp
s_clone(typename type_traits::tp_const t,u32 estate)55 auto_type_toolbox<T>::s_clone(typename type_traits::tp_const t, u32 estate){
56    ASSERT_RET(t != NIL, NIL);
57    type_traits::tp self = su_NEW(typename type_traits::type);
58    if(self->assign(t, estate) != 0){
59       su_DEL(self);
60       self = NIL;
61    }
62    return self;
63 }
64 template<class T>
65 PRI STA void
s_delete(typename type_traits::tp self)66 auto_type_toolbox<T>::s_delete(typename type_traits::tp self){
67    ASSERT_RET_VOID(self != NIL);
68    su_DEL(self);
69 }
70 template<class T>
71 PRI STA typename type_traits::tp
s_assign(typename type_traits::tp self,typename type_traits::tp_const t,u32 estate)72 auto_type_toolbox<T>::s_assign(typename type_traits::tp self,
73       typename type_traits::tp_const t, u32 estate){
74    ASSERT_RET(self != NIL, NIL);
75    ASSER_RET(t != NIL, self);
76    if(self != t){
77       if(self->assign(t, estate) != 0)
78          self = NIL;
79    }
80    return self;
81 }
82 template<class T>
83 PRI STA sz
s_compare(typename type_traits::tp_const self,typename type_traits::tp_const t)84 auto_type_toolbox<T>::s_compare(typename type_traits::tp_const self,
85       typename type_traits::tp_const t){
86    ASSERT_RET(self != NIL, (t != NIL) ? -1 : 0);
87    ASSERT_RET(t != NIL, 1);
88    return self->compare(*t);
89 }
90 template<class T>
91 PRI STA uz
s_hash(typename type_traits::tp_const self)92 auto_type_toolbox<T>::s_hash(typename type_traits::tp_const self){
93    ASSERT_RET(self != NIL, 0);
94    return self->hash();
95 }
96 template<class T>
97 STA type_toolbox<T> const auto_type_toolbox<T>::instance =
98       su_TYPE_TOOLBOX_I9R(&s_clone, &s_delete, &s_assign, &s_compare, &s_hash);
99 #endif // !su_A_T_T_DECL_ONLY
100 NSPC_END(su)
101 #include <su/code-ou.h>
102