]> git.cworth.org Git - vogl/blob - src/extlib/loki/include/loki/yasli/yasli_protocols.h
Initial vogl checkin
[vogl] / src / extlib / loki / include / loki / yasli / yasli_protocols.h
1 #ifndef YASLI_PROTOCOLS_H_
2 #define YASLI_PROTOCOLS_H_
3
4 // $Id: yasli_protocols.h 754 2006-10-17 19:59:11Z syntheticpp $
5
6
7 #include <complex>
8 #include <functional>
9 #include "yasli_memory.h"
10 #include <memory.h>
11
12 namespace yasli_protocols
13 {
14
15 // Most conservative
16 template <class T>
17 struct safe_move_traits
18 {
19         static T *destructive_move(
20             T *begin,
21             T *end,
22             void *dest)
23         {
24                 T *tdest = static_cast<T *>(dest);
25                 typedef std::less<T *> ls;
26                 assert(!ls()(tdest, end) || ls()(tdest, begin - (end - begin)));
27                 tdest = /*yasli*/std::uninitialized_copy(begin, end, tdest);
28                 if (yasli_nstd::is_class<T>::value)
29                 {
30                         for (; begin != end; ++begin)
31                         {
32                                 begin->~T();
33                         }
34                 }
35                 return tdest;
36         }
37         static T *nondestructive_move(
38             T *begin,
39             T *end,
40             void *dest)
41         {
42                 T *d = static_cast<T *>(dest);
43                 for (; begin != end; ++begin, ++d)
44                         new(d) T(*begin);
45                 return d;
46         }
47         static T *nondestructive_assign_move(
48             T *begin,
49             T *end,
50             T *dest)
51         {
52                 if (begin <= dest && dest < end)
53                 {
54                         dest += end - begin;
55                         T *const result = dest;
56                         while (begin != end)
57                                 *--dest = *--end;
58                         return result;
59                 }
60                 for (; begin != end; ++begin, ++dest)
61                         *dest = *begin;
62                 return dest;
63         }
64 };
65
66
67 template <class T>
68 struct memmove_traits
69 {
70         static T *destructive_move(
71             T *begin,
72             T *end,
73             void *dest)
74         {
75                 memmove(dest, begin, (end - begin) * sizeof(T));
76                 return static_cast<T *>(dest) + (end - begin);
77         };
78         static T *nondestructive_move(
79             T *begin,
80             T *end,
81             void *dest)
82         {
83                 memmove(dest, begin, (end - begin) * sizeof(T));
84                 return static_cast<T *>(dest) + (end - begin);
85         }
86         static T *nondestructive_assign_move(
87             T *begin,
88             T *end,
89             T *dest)
90         {
91                 yasli_nstd::destroy_range(begin, end);
92                 memmove(dest, begin, (end - begin) * sizeof(T));
93                 return static_cast<T *>(dest) + (end - begin);
94         }
95 };
96
97 // for nonspecialized classes, use safe_move_traits
98 template <class T>
99 struct move_traits: public
100                 yasli_nstd::type_selector<yasli_nstd::is_class<T>::value == 0,
101                 memmove_traits<T>,
102                 safe_move_traits<T>
103                 >::result
104         {};
105
106 template <class T>
107 struct move_traits<std::complex<T> >:public
108 yasli_nstd::type_selector<sizeof(std::complex<T>) == 2 * sizeof(T),
109            memmove_traits< std::complex<T> >,
110            safe_move_traits< std::complex<T> >
111            >::result
112            {
113            };
114 }
115
116 #endif // YASLI_PROTOCOLS_H_