360168d55df417b3bb91a6e71271408404de8d85
[ardour.git] / libs / audiographer / audiographer / type_utils.h
1 #ifndef AUDIOGRAPHER_TYPE_UTILS_H
2 #define AUDIOGRAPHER_TYPE_UTILS_H
3
4 #include "audiographer/types.h"
5 #include <boost/static_assert.hpp>
6 #include <boost/type_traits.hpp>
7 #include <memory>
8 #include <algorithm>
9
10 namespace AudioGrapher
11 {
12
13 /// Non-template base class for TypeUtils
14 class TypeUtilsBase
15 {
16   protected:
17         
18         template<typename T, bool b>
19         static void do_zero_fill(T * buffer, framecnt_t frames, const boost::integral_constant<bool, b>&)
20                 { std::uninitialized_fill_n (buffer, frames, T()); }
21
22         template<typename T>
23         static void do_zero_fill(T * buffer, framecnt_t frames, const boost::true_type&)
24                 { memset (buffer, 0, frames * sizeof(T)); }
25 };
26
27 /// Utilities for initializing, copying, moving, etc. data
28 template<typename T = DefaultSampleType>
29 class TypeUtils : private TypeUtilsBase
30 {
31         BOOST_STATIC_ASSERT (boost::has_trivial_destructor<T>::value);
32         
33         typedef boost::integral_constant<bool, 
34                         boost::is_floating_point<T>::value ||
35                         boost::is_signed<T>::value> zero_fillable;
36   public:
37         /** Fill buffer with a zero value
38           * The value used for filling is either 0 or the value of T()
39           * if T is not a floating point or signed integer type
40           * \n RT safe
41           */
42         inline static void zero_fill (T * buffer, framecnt_t frames)
43                 { do_zero_fill(buffer, frames, zero_fillable()); }
44         
45         /** Copies \a frames frames of data from \a source to \a destination
46           * The source and destination may NOT overlap.
47           * \n RT safe
48           */
49         inline static void copy (T const * source, T * destination, framecnt_t frames)
50                 { std::uninitialized_copy (source, &source[frames], destination); }
51         
52         /** Moves \a frames frames of data from \a source to \a destination
53           * The source and destination may overlap in any way.
54           * \n RT safe
55           */
56         inline static void move (T const * source, T * destination, framecnt_t frames)
57         {
58                 if (destination < source) {
59                         std::copy (source, &source[frames], destination);
60                 } else if (destination > source) {
61                         std::copy_backward (source, &source[frames], destination + frames);
62                 }
63         }
64 };
65
66
67 } // namespace
68
69 #endif // AUDIOGRAPHER_TYPE_UTILS_H