-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtraits.hpp
More file actions
184 lines (159 loc) · 4.61 KB
/
traits.hpp
File metadata and controls
184 lines (159 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/* -*- coding: utf-8;mode:c++;c-file-style:"stroustrup" -*- */
/*
Licensed under the terms of the BSD 3-Clause
(see plotpy/__init__.py for details)
Two lines of the following code are distributed under LGPL license terms and
with a different copyright. These two lines are the Visual Studio x86_64
(_M_X64) inline versions of lrint() and lrintf() functions, and were adapted
from fast_convert.h (SpanDSP), which is:
Copyright © 2009 Steve Underwood
All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 2.1,
as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
*/
#ifndef __TRAITS_HPP__
#define __TRAITS_HPP__
#include <math.h>
/* this class (real_trait) is used
to make the code somewhat independent of
the real type used (float or double).
we don't provide a template parameter
on the Point* class to avoid clutter but
changing a simple typedef is all it takes
to switch from float to double type
*/
/* MSVC does not have lrint/lrintf */
#ifdef _MSC_VER
#if _MSC_VER < 1900 // (Visual Studio 2015 version 14.0)
#include <intrin.h>
__inline long int lrint(double f)
{
#ifdef _M_X64
return (long int)_mm_cvtsd_si64x(_mm_loadu_pd((const double *)&f));
#else
int i;
_asm
{
fld f
fistp i
}
return i;
#endif
}
__inline long int lrintf(float f)
{
#ifdef _M_X64
return _mm_cvt_ss2si(_mm_load_ss((const float *)&f));
#else
int i;
_asm
{
fld f
fistp i
}
return i;
#endif
}
#endif
#endif
typedef int fixed;
template <typename T>
struct num_trait
{
typedef T value_type;
typedef long large_type;
static int toint(value_type v) { return (int)v; }
static value_type fromdouble(double v) { return (value_type)v; }
static const bool is_integer = true;
};
template <>
struct num_trait<float>
{
typedef float value_type;
typedef float large_type;
static int toint(value_type v) { return lrintf(v); }
static value_type fromdouble(double v) { return (value_type)v; }
static const bool is_integer = false;
};
template <>
struct num_trait<double>
{
typedef double value_type;
typedef double large_type;
static int toint(value_type v) { return lrint(v); }
static value_type fromdouble(double v) { return (value_type)v; }
static const bool is_integer = false;
};
template <>
struct num_trait<fixed>
{
typedef fixed value_type;
typedef fixed large_type;
static int toint(value_type v) { return (v >> 15); }
static value_type fromdouble(double v) { return lrint(v * 32768.); }
static const bool is_integer = false;
};
template <>
struct num_trait<npy_int64>
{
typedef npy_int64 value_type;
typedef signed __int64 large_type;
static int toint(value_type v) { return (int)v; }
static value_type fromdouble(double v) { return (value_type)v; }
static const bool is_integer = true;
};
template <>
struct num_trait<npy_uint64>
{
typedef npy_uint64 value_type;
typedef unsigned __int64 large_type;
static int toint(value_type v) { return static_cast<int>(v); }
static value_type fromdouble(double v) { return static_cast<value_type>(v); }
static const bool is_integer = true;
};
template <class A>
static void dispatch_array(int npy_type, A &algo)
{
switch (npy_type)
{
case NPY_FLOAT32:
algo.template run<npy_float32>();
break;
case NPY_FLOAT64:
algo.template run<npy_float64>();
break;
case NPY_UINT64:
algo.template run<npy_uint64>();
break;
case NPY_INT64:
algo.template run<npy_int64>();
break;
case NPY_UINT32:
algo.template run<npy_uint32>();
break;
case NPY_INT32:
algo.template run<npy_int32>();
break;
case NPY_UINT16:
algo.template run<npy_uint16>();
break;
case NPY_INT16:
algo.template run<npy_int16>();
break;
case NPY_UINT8:
algo.template run<npy_uint8>();
break;
case NPY_INT8:
algo.template run<npy_int8>();
break;
case NPY_BOOL:
algo.template run<npy_bool>();
break;
}
}
#endif