Skip to content

Commit 8edd7df

Browse files
authored
Array cast support for custom types (#100)
- Add `cast<T>` function for array; - Mark `to_vec` and `cast` as noexcept; - Remove `array_cast` function; - Fix conanfile recipe;
1 parent 509bb41 commit 8edd7df

File tree

6 files changed

+47
-34
lines changed

6 files changed

+47
-34
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.15)
2-
project(dsplib LANGUAGES CXX VERSION 0.55.3)
2+
project(dsplib LANGUAGES CXX VERSION 1.0.0)
33

44
set(CMAKE_CXX_STANDARD 17)
55
set(CMAKE_CXX_STANDARD_REQUIRED ON)

conanfile.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from conan import ConanFile
22
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout
3+
from conan.tools.build import check_min_cppstd
34
import re
45

6+
required_conan_version = ">=2.1.0"
7+
58

69
def get_version():
710
try:
@@ -16,30 +19,35 @@ def get_version():
1619
class DsplibConan(ConanFile):
1720
name = "dsplib"
1821
version = get_version()
19-
2022
license = "MIT"
2123
author = "Vitaly Yulis ([email protected])"
2224
url = "https://github.com/vitalsong/dsplib"
2325
description = "C++ DSP library for MATLAB/Octave similar programming"
2426
topics = ("dsp", "matlab", "c++17", "audio")
2527

2628
settings = "os", "compiler", "build_type", "arch"
29+
2730
options = {
2831
"shared": [True, False],
2932
"fPIC": [True, False],
3033
"float32": [True, False],
3134
"noexcept": [True, False],
3235
}
36+
3337
default_options = {
3438
"shared": False,
3539
"fPIC": True,
3640
"float32": False,
3741
"noexcept": False,
3842
}
39-
generators = "CMakeDeps"
4043

41-
exports_sources = "cmake/*", "CMakeLists.txt", "lib/*", "include/*"
44+
generators = ["CMakeDeps"]
4245

46+
exports_sources = "cmake/*", "CMakeLists.txt", "lib/*", "include/*"
47+
48+
def validate(self):
49+
check_min_cppstd(self, 17)
50+
4351
def config_options(self):
4452
if self.settings.os == "Windows":
4553
del self.options.fPIC
@@ -49,10 +57,11 @@ def layout(self):
4957

5058
def generate(self):
5159
tc = CMakeToolchain(self)
52-
if self.options.float32:
53-
tc.variables["DSPLIB_USE_FLOAT32"] = "ON"
54-
if self.options.noexcept:
55-
tc.variables["DSPLIB_NO_EXCEPTIONS"] = "ON"
60+
tc.variables["DSPLIB_USE_FLOAT32"] = self.options.float32
61+
tc.variables["DSPLIB_NO_EXCEPTIONS"] = self.options.noexcept
62+
tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
63+
if self.options.get_safe("fPIC"):
64+
tc.variables["CMAKE_POSITION_INDEPENDENT_CODE"] = self.options.fPIC
5665
tc.generate()
5766

5867
def build(self):

include/dsplib/array.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -359,34 +359,44 @@ class base_array
359359
}
360360

361361
//concatenate syntax
362-
//TODO: mark as deprecated
363362
template<class T2, class R = ResultType<T, T2>>
364-
base_array<R>& operator|=(const base_array<T2>& rhs) {
363+
base_array& operator|=(const base_array<T2>& rhs) {
364+
static_assert(std::is_same_v<T, R>, "not supported array cast");
365365
_vec.insert(_vec.end(), rhs.begin(), rhs.end());
366366
return *this;
367367
}
368368

369369
template<class T2, class R = ResultType<T, T2>>
370370
base_array<R> operator|(const base_array<T2>& rhs) const {
371-
auto temp = array_cast<R>(*this);
372-
temp |= array_cast<R>(rhs);
373-
return temp;
371+
auto r = this->cast<R>();
372+
r |= rhs;
373+
return r;
374374
}
375375

376376
template<typename R>
377-
std::vector<R> to_vec() const {
377+
[[nodiscard]] std::vector<R> to_vec() const noexcept {
378378
if constexpr (std::is_same_v<T, R>) {
379379
return _vec;
380380
} else {
381-
static_assert(std::is_convertible_v<T, R>, "type is not convertible");
381+
static_assert(std::is_convertible_v<T, R>, "type must be convertible");
382382
return std::vector<R>(_vec.begin(), _vec.end());
383383
}
384384
}
385385

386-
const std::vector<T>& to_vec() const noexcept {
386+
[[nodiscard]] const std::vector<T>& to_vec() const noexcept {
387387
return _vec;
388388
}
389389

390+
template<typename R>
391+
[[nodiscard]] auto cast() const noexcept {
392+
if constexpr (std::is_same_v<T, R>) {
393+
return *this;
394+
} else {
395+
static_assert(std::is_convertible_v<T, R>, "type must be convertible");
396+
return base_array<R>(this->to_vec<R>());
397+
}
398+
}
399+
390400
//apply per element function
391401
template<class Fn>
392402
auto apply(Fn func) const {

include/dsplib/traits.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,6 @@ constexpr auto reduce_operator_type() noexcept {
3838
template<typename T1, typename T2>
3939
using ResultType = decltype(reduce_operator_type<T1, T2>());
4040

41-
template<typename T_dst, typename T_src>
42-
constexpr base_array<T_dst> array_cast(const base_array<T_src>& src) noexcept {
43-
static_assert(is_scalar_v<T_src> && is_scalar_v<T_dst>, "Types must be scalar");
44-
static_assert(!(is_complex_v<T_src> && !is_complex_v<T_dst>), "Complex to real cast is not allowed");
45-
if constexpr (std::is_same_v<T_src, T_dst>) {
46-
return src;
47-
} else if constexpr (!is_complex_v<T_src> && is_complex_v<T_dst>) {
48-
base_array<T_dst> dst(src.size());
49-
for (int i = 0; i < src.size(); ++i) {
50-
dst[i].re = static_cast<real_t>(src[i]);
51-
}
52-
return dst;
53-
} else {
54-
return base_array<T_dst>(src);
55-
}
56-
}
57-
5841
//rules for implicit array conversion
5942
//TODO: use static_assert and verbose error message
6043
template<typename T_src, typename T_dst>

lib/math.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ arr_cmplx power(const arr_cmplx& x, real_t n) {
471471
template<typename T>
472472
static base_array<T> _power(const base_array<T>& x, int n) {
473473
if (n == 0) {
474-
return array_cast<T>(ones(x.size()));
474+
return ones(x.size()).template cast<T>();
475475
}
476476
if (n == 1) {
477477
return x;

tests/arr_real_test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ TEST(ArrRealTest, Cast) {
3636
const arr_real x2(x1);
3737
ASSERT_EQ_ARR_REAL(x1, x2);
3838
}
39+
{
40+
const arr_int x1 = arange(0, 10).cast<int>();
41+
const arr_real x2(x1);
42+
ASSERT_EQ_ARR_REAL(x1, x2);
43+
}
44+
{
45+
const arr_real x1 = arange(0, 10);
46+
const arr_cmplx x2 = x1.cast<cmplx_t>();
47+
ASSERT_EQ_ARR_REAL(real(x2), x1);
48+
ASSERT_EQ_ARR_REAL(imag(x2), zeros(x1.size()));
49+
}
3950
{
4051
arr_real x1 = {1, 2, 3, 4, 5};
4152
x1 = x1;

0 commit comments

Comments
 (0)