-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtraits.hpp
More file actions
162 lines (141 loc) · 4.01 KB
/
traits.hpp
File metadata and controls
162 lines (141 loc) · 4.01 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
/* -*- 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 <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