coder_array.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786
  1. /* Copyright 2019 The Mathworks, Inc. */
  2. /* Copied from
  3. * fullfile(matlabroot,'extern','include','coder','coder_array','coder_array_rtw_cpp11.h') */
  4. #ifndef _mw_coder_array_cpp11_h
  5. #define _mw_coder_array_cpp11_h
  6. // Usage:
  7. //
  8. // coder::array<T, N>: T base type of data, N number of dimensions
  9. //
  10. // coder::array()
  11. // : default constructor
  12. // coder::array(coder::array const &)
  13. // : copy constructor (always make a deep copy of other array)
  14. // coder::array(T const *data, SizeType const *sz)
  15. // : Set data with sizes of this array.
  16. // : (Data is not copied, data is not deleted)
  17. // coder::array::operator = (coder coder::array &)
  18. // : Assign into this array;
  19. // : delete its previous contents (if owning the data.)
  20. // set(T const *data, SizeType sz1, SizeType sz2, ...)
  21. // : Set data with dimensions.
  22. // : (Data is not copied, data is not deleted)
  23. // set_size(SizeType sz1, SizeType sz2, ...)
  24. // : Set sizes of array. Reallocate memory of data if needed.
  25. // bool is_owner() : Return true if the data is owned by the class.
  26. // void set_owner(b) : Set if the data is owned by the class.
  27. // SizeType capacity() : How many entries are reserved by memory allocation.
  28. // reshape( SizeType sz1, SizeType sz2, ...)
  29. // : Reshape array to a different ND shape. Do not copy the data.
  30. // : The number of elements must not be changed (numel()==sz1*sz2*...)
  31. // : Return the array with possibly new number of dimensions.
  32. // clear() : Reset array to be empty.
  33. // SizeType numel() : Return the number of elements.
  34. // operator [] (SizeType index) : Extract element at linear index (0 based.)
  35. // size(SizeType dimension) : Size of array of the provided dimension.
  36. // SizeType * size() : Return the pointer to all the sizes of this array.
  37. // SizeType index(SizeType i1, SizeType i2, ...)
  38. // : Compute the linear index from ND index (i1,i2,...)
  39. // at(SizeType i1, SizeType i2, ...) : The element at index (i1,i2,...)
  40. #include <cassert>
  41. #include <cstring>
  42. #include <iterator>
  43. #include <string>
  44. #include <vector>
  45. #ifndef INT32_T
  46. #include "../rtwtypes.h"
  47. #endif
  48. namespace coder {
  49. #ifndef CODER_ARRAY_NEW_DELETE
  50. #define CODER_ARRAY_NEW_DELETE
  51. #define CODER_NEW(T, N) new T[N]
  52. #define CODER_DELETE(P) delete[](P)
  53. #endif
  54. #ifndef CODER_ARRAY_SIZE_TYPE_DEFINED
  55. using SizeType = int;
  56. #endif
  57. namespace std = ::std;
  58. namespace detail {
  59. #ifndef CODER_ARRAY_DATA_PTR_DEFINED
  60. template <typename T, typename SZ>
  61. class data_ptr {
  62. public:
  63. using value_type = T;
  64. using size_type = SZ;
  65. data_ptr()
  66. : data_(nullptr)
  67. , size_(0)
  68. , capacity_(0)
  69. , owner_(false) {
  70. }
  71. data_ptr(T* _data, SZ _sz)
  72. : data_(_data)
  73. , size_(_sz)
  74. , capacity_(_sz)
  75. , owner_(false) {
  76. }
  77. data_ptr(data_ptr const& _other)
  78. : data_(_other.owner_ ? nullptr : _other.data_)
  79. , size_(_other.owner_ ? 0 : _other.size_)
  80. , capacity_(_other.owner_ ? 0 : _other.capacity_)
  81. , owner_(_other.owner_) {
  82. if (owner_) {
  83. resize(_other.size_);
  84. (void)std::copy(_other.data_, _other.data_ + size_, data_);
  85. }
  86. }
  87. ~data_ptr() {
  88. if (owner_) {
  89. CODER_DELETE(data_);
  90. }
  91. }
  92. SZ capacity() const {
  93. return capacity_;
  94. }
  95. void reserve(SZ _n) {
  96. if (_n > capacity_) {
  97. T* const new_data{CODER_NEW(T, _n)};
  98. (void)std::copy(data_, data_ + size_, new_data);
  99. if (owner_) {
  100. CODER_DELETE(data_);
  101. }
  102. data_ = new_data;
  103. capacity_ = _n;
  104. owner_ = true;
  105. }
  106. }
  107. void resize(SZ _n) {
  108. reserve(_n);
  109. size_ = _n;
  110. }
  111. private:
  112. // Prohibit use of assignment operator to prevent subtle bugs
  113. void operator=(data_ptr<T, SZ> const& _other);
  114. public:
  115. void set(T* _data, SZ _sz) {
  116. if (owner_) {
  117. CODER_DELETE(data_);
  118. }
  119. data_ = _data;
  120. size_ = _sz;
  121. owner_ = false;
  122. capacity_ = size_;
  123. }
  124. void copy(T const* const _data, SZ _size) {
  125. if (data_ == _data) {
  126. size_ = _size;
  127. return;
  128. }
  129. if (owner_) {
  130. CODER_DELETE(data_);
  131. }
  132. data_ = CODER_NEW(T, _size);
  133. owner_ = true;
  134. size_ = _size;
  135. capacity_ = size_;
  136. (void)std::copy(_data, _data + _size, data_);
  137. }
  138. void copy(data_ptr<T, SZ> const& _other) {
  139. copy(_other.data_, _other.size_);
  140. }
  141. operator T*() {
  142. return &data_[0];
  143. }
  144. operator T const *() const {
  145. return &data_[0];
  146. }
  147. T& operator[](SZ _index) {
  148. return data_[_index];
  149. }
  150. T const& operator[](SZ _index) const {
  151. return data_[_index];
  152. }
  153. T* operator->() {
  154. return data_;
  155. }
  156. T const* operator->() const {
  157. return data_;
  158. }
  159. bool is_null() const {
  160. return data_ == nullptr;
  161. }
  162. void clear() {
  163. if (owner_) {
  164. CODER_DELETE(data_);
  165. }
  166. data_ = nullptr;
  167. size_ = 0;
  168. capacity_ = 0;
  169. owner_ = false;
  170. }
  171. bool is_owner() const {
  172. return owner_;
  173. }
  174. void set_owner(bool _b) {
  175. owner_ = _b;
  176. }
  177. private:
  178. T* data_;
  179. SZ size_;
  180. SZ capacity_;
  181. bool owner_;
  182. };
  183. #endif
  184. } // namespace detail
  185. // Implementing the random access iterator class so coder::array can be
  186. // used in STL iterators.
  187. template <typename T>
  188. class array_iterator : public std::iterator<std::random_access_iterator_tag,
  189. typename T::value_type,
  190. typename T::size_type> {
  191. public:
  192. array_iterator()
  193. : arr_(nullptr)
  194. , i_(0) {
  195. }
  196. array_iterator(array_iterator<T> const& other)
  197. : arr_(other.arr_)
  198. , i_(other.i_) {
  199. }
  200. ~array_iterator() {
  201. }
  202. typename T::value_type& operator*() const {
  203. return (*arr_)[i_];
  204. }
  205. typename T::value_type* operator->() const {
  206. return &(*arr_)[i_];
  207. }
  208. typename T::value_type& operator[](typename T::size_type _di) const {
  209. return (*arr_)[i_ + _di];
  210. }
  211. array_iterator<T>& operator++() {
  212. ++i_;
  213. return *this;
  214. }
  215. array_iterator<T>& operator--() {
  216. --i_;
  217. return *this;
  218. }
  219. array_iterator<T> operator++(int) {
  220. array_iterator<T> cp{*this};
  221. ++i_;
  222. return cp;
  223. }
  224. array_iterator<T> operator--(int) {
  225. array_iterator<T> cp{*this};
  226. --i_;
  227. return cp;
  228. }
  229. array_iterator<T>& operator=(array_iterator<T> const& _other) {
  230. this->i_ = _other.i_;
  231. return *this;
  232. }
  233. bool operator==(array_iterator<T> const& _other) const {
  234. return i_ == _other.i_;
  235. }
  236. bool operator!=(array_iterator<T> const& _other) const {
  237. return i_ != _other.i_;
  238. }
  239. bool operator<(array_iterator<T> const& _other) const {
  240. return i_ < _other.i_;
  241. }
  242. bool operator>(array_iterator<T> const& _other) const {
  243. return i_ > _other.i_;
  244. }
  245. bool operator<=(array_iterator<T> const& _other) const {
  246. return i_ <= _other.i_;
  247. }
  248. bool operator>=(array_iterator<T> const& _other) const {
  249. return i_ >= _other.i_;
  250. }
  251. array_iterator<T> operator+(typename T::size_type _add) const {
  252. array_iterator<T> cp{*this};
  253. cp.i_ += _add;
  254. return cp;
  255. }
  256. array_iterator<T>& operator+=(typename T::size_type _add) {
  257. this->i_ += _add;
  258. return *this;
  259. }
  260. array_iterator<T> operator-(typename T::size_type _subtract) const {
  261. array_iterator<T> cp{*this};
  262. cp.i_ -= _subtract;
  263. return cp;
  264. }
  265. array_iterator<T>& operator-=(typename T::size_type _subtract) {
  266. this->i_ -= _subtract;
  267. return *this;
  268. }
  269. typename T::size_type operator-(array_iterator<T> const& _other) const {
  270. return static_cast<typename T::size_type>(this->i_ - _other.i_);
  271. }
  272. array_iterator(T* _arr, typename T::size_type _i)
  273. : arr_(_arr)
  274. , i_(_i) {
  275. }
  276. private:
  277. T* arr_;
  278. typename T::size_type i_;
  279. };
  280. // Const version of the array iterator.
  281. template <typename T>
  282. class const_array_iterator : public std::iterator<std::random_access_iterator_tag,
  283. typename T::value_type,
  284. typename T::size_type> {
  285. public:
  286. const_array_iterator()
  287. : arr_(nullptr)
  288. , i_(0) {
  289. }
  290. const_array_iterator(const_array_iterator<T> const& other)
  291. : arr_(other.arr_)
  292. , i_(other.i_) {
  293. }
  294. ~const_array_iterator() {
  295. }
  296. typename T::value_type const& operator*() const {
  297. return (*arr_)[i_];
  298. }
  299. typename T::value_type const* operator->() const {
  300. return &(*arr_)[i_];
  301. }
  302. typename T::value_type const& operator[](typename T::size_type _di) const {
  303. return (*arr_)[i_ + _di];
  304. }
  305. const_array_iterator<T>& operator++() {
  306. ++i_;
  307. return *this;
  308. }
  309. const_array_iterator<T>& operator--() {
  310. --i_;
  311. return *this;
  312. }
  313. const_array_iterator<T> operator++(int) {
  314. const_array_iterator<T> copy{*this};
  315. ++i_;
  316. return copy;
  317. }
  318. const_array_iterator<T> operator--(int) {
  319. const_array_iterator copy{*this};
  320. --i_;
  321. return copy;
  322. }
  323. const_array_iterator<T>& operator=(const_array_iterator<T> const& _other) {
  324. this->i_ = _other.i_;
  325. return *this;
  326. }
  327. bool operator==(const_array_iterator<T> const& _other) const {
  328. return i_ == _other.i_;
  329. }
  330. bool operator!=(const_array_iterator<T> const& _other) const {
  331. return i_ != _other.i_;
  332. }
  333. bool operator<(const_array_iterator<T> const& _other) const {
  334. return i_ < _other.i_;
  335. }
  336. bool operator>(const_array_iterator<T> const& _other) const {
  337. return i_ > _other.i_;
  338. }
  339. bool operator<=(const_array_iterator<T> const& _other) const {
  340. return i_ <= _other.i_;
  341. }
  342. bool operator>=(const_array_iterator<T> const& _other) const {
  343. return i_ >= _other.i_;
  344. }
  345. const_array_iterator<T> operator+(typename T::size_type _add) const {
  346. const_array_iterator<T> cp{*this};
  347. cp.i_ += _add;
  348. return cp;
  349. }
  350. const_array_iterator<T>& operator+=(typename T::size_type _add) {
  351. this->i_ += _add;
  352. return *this;
  353. }
  354. const_array_iterator<T> operator-(typename T::size_type _subtract) const {
  355. const_array_iterator<T> cp{*this};
  356. cp.i_ -= _subtract;
  357. return cp;
  358. }
  359. const_array_iterator<T>& operator-=(typename T::size_type _subtract) {
  360. this->i_ -= _subtract;
  361. return *this;
  362. }
  363. typename T::size_type operator-(const_array_iterator<T> const& _other) const {
  364. return static_cast<typename T::size_type>(this->i_ - _other.i_);
  365. }
  366. const_array_iterator(T const* _arr, typename T::size_type _i)
  367. : arr_(_arr)
  368. , i_(_i) {
  369. }
  370. private:
  371. T const* arr_;
  372. typename T::size_type i_;
  373. typename T::size_type n_;
  374. };
  375. namespace detail {
  376. // detail::numel<N>: Compile-time product of the given size vector of length N.
  377. template <int N>
  378. class numel {
  379. public:
  380. template <typename SZ>
  381. static SZ compute(SZ _size[]) {
  382. return _size[N - 1] * numel<N - 1>::compute(_size);
  383. }
  384. };
  385. template <>
  386. class numel<0> {
  387. public:
  388. template <typename SZ>
  389. static SZ compute(SZ[]) {
  390. return 1;
  391. }
  392. };
  393. // Compute the product for a set of numeric arguments: product<int32_T>(10, 20, 30, ...) =>
  394. // 10*20*30*...
  395. template <typename SZ, typename First, typename... Rest>
  396. struct product_i {
  397. static SZ compute(First _f, Rest... _rest) {
  398. return _f * product_i<SZ, Rest...>::compute(_rest...);
  399. }
  400. };
  401. template <typename SZ, typename Last>
  402. struct product_i<SZ, Last> {
  403. static SZ compute(Last _l) {
  404. return _l;
  405. }
  406. };
  407. template <typename SZ, typename... Args>
  408. SZ product(Args... args) {
  409. return product_i<SZ, Args...>::compute(args...);
  410. }
  411. // Compute flat index from (column-major) ND size vector and a list of indices.
  412. template <int I>
  413. class index_nd {
  414. public:
  415. template <typename SZ>
  416. static SZ compute(SZ const _size[], SZ const _indices[]) {
  417. SZ const weight{numel<I - 1>::compute(_size)};
  418. return weight * _indices[I - 1] + index_nd<I - 1>::compute(_size, _indices);
  419. }
  420. };
  421. template <>
  422. class index_nd<0> {
  423. public:
  424. template <typename SZ>
  425. static SZ compute(SZ[], SZ[]) {
  426. return 0;
  427. }
  428. };
  429. template <bool Cond>
  430. struct match_dimensions {};
  431. template <>
  432. struct match_dimensions<true> {
  433. static void check() {
  434. }
  435. };
  436. } // namespace detail
  437. // Base class for code::array. SZ is the type used for sizes (currently int32_t.)
  438. // Overloading up to 10 dimensions (not using variadic templates to
  439. // stay compatible with C++98.)
  440. template <typename T, typename SZ, int N>
  441. class array_base {
  442. public:
  443. using value_type = T;
  444. using size_type = SZ;
  445. array_base() {
  446. (void)::memset(size_, 0, sizeof(SZ) * N);
  447. }
  448. array_base(T* _data, SZ const* _sz)
  449. : data_(_data, coder::detail::numel<N>::compute(_sz)) {
  450. (void)std::copy(_sz, _sz + N, size_);
  451. }
  452. array_base& operator=(array_base const& _other) {
  453. data_.copy(_other.data_);
  454. (void)std::copy(_other.size_, _other.size_ + N, size_);
  455. return *this;
  456. }
  457. template <typename... Dims>
  458. void set(T* _data, Dims... dims) {
  459. coder::detail::match_dimensions<N == sizeof...(dims)>::check();
  460. data_.set(_data, coder::detail::product<SZ>(dims...));
  461. set_size_i<0>(dims...);
  462. }
  463. bool is_owner() const {
  464. return data_.is_owner();
  465. }
  466. void set_owner(bool b) {
  467. data_.set_owner(b);
  468. }
  469. SZ capacity() const {
  470. return data_.capacity();
  471. }
  472. private:
  473. template <SZ _i, typename First, typename... Rest>
  474. void set_size_i(First f, Rest... rest) {
  475. size_[_i] = f;
  476. set_size_i<_i + 1, Rest...>(rest...);
  477. }
  478. template <SZ _i, typename Last>
  479. void set_size_i(Last l) {
  480. size_[_i] = l;
  481. }
  482. public:
  483. template <typename... Dims>
  484. void set_size(Dims... dims) {
  485. coder::detail::match_dimensions<N == sizeof...(dims)>::check();
  486. set_size_i<0>(dims...);
  487. ensureCapacity(numel());
  488. }
  489. template <SizeType N1>
  490. array_base<T, SZ, N1> reshape_n(SZ const (&_ns)[N1]) const {
  491. array_base<T, SZ, N1> reshaped{const_cast<T*>(&data_[0]), _ns};
  492. return reshaped;
  493. }
  494. template <typename... Dims>
  495. array_base<T, SZ, static_cast<SZ>(sizeof...(Dims))> reshape(Dims... dims) const {
  496. SZ const ns[]{static_cast<SZ>(dims)...};
  497. return reshape_n(ns);
  498. }
  499. T& operator[](SZ _index) {
  500. return data_[_index];
  501. }
  502. T const& operator[](SZ _index) const {
  503. return data_[_index];
  504. }
  505. void clear() {
  506. data_.clear();
  507. }
  508. T* data() {
  509. return data_;
  510. }
  511. T const* data() const {
  512. return data_;
  513. }
  514. SZ const* size() const {
  515. return &size_[0];
  516. }
  517. SZ size(SZ _index) const {
  518. return size_[_index];
  519. }
  520. SZ numel() const {
  521. return coder::detail::numel<N>::compute(size_);
  522. }
  523. template <typename... Dims>
  524. SZ index(Dims... _dims) const {
  525. coder::detail::match_dimensions<N == sizeof...(_dims)>::check();
  526. SZ const indices[]{static_cast<SZ>(_dims)...};
  527. return coder::detail::index_nd<static_cast<SZ>(sizeof...(_dims))>::compute(size_, indices);
  528. }
  529. template <typename... Dims>
  530. T& at(Dims... _i) {
  531. coder::detail::match_dimensions<N == sizeof...(_i)>::check();
  532. return data_[index(_i...)];
  533. }
  534. template <typename... Dims>
  535. T const& at(Dims... _i) const {
  536. coder::detail::match_dimensions<N == sizeof...(_i)>::check();
  537. return data_[index(_i...)];
  538. }
  539. array_iterator<array_base<T, SZ, N> > begin() {
  540. return array_iterator<array_base<T, SZ, N> >(this, 0);
  541. }
  542. array_iterator<array_base<T, SZ, N> > end() {
  543. return array_iterator<array_base<T, SZ, N> >(this, this->numel());
  544. }
  545. const_array_iterator<array_base<T, SZ, N> > begin() const {
  546. return const_array_iterator<array_base<T, SZ, N> >(this, 0);
  547. }
  548. const_array_iterator<array_base<T, SZ, N> > end() const {
  549. return const_array_iterator<array_base<T, SZ, N> >(this, this->numel());
  550. }
  551. protected:
  552. coder::detail::data_ptr<T, SZ> data_;
  553. SZ size_[N];
  554. private:
  555. void ensureCapacity(SZ _newNumel) {
  556. if (_newNumel > data_.capacity()) {
  557. SZ i{data_.capacity()};
  558. if (i < 16) {
  559. i = 16;
  560. }
  561. while (i < _newNumel) {
  562. if (i > 1073741823) {
  563. i = MAX_int32_T;
  564. } else {
  565. i *= 2;
  566. }
  567. }
  568. data_.reserve(i);
  569. }
  570. data_.resize(_newNumel);
  571. }
  572. };
  573. // The standard coder::array class with base type and number of dimensions.
  574. template <typename T, int N>
  575. class array : public array_base<T, SizeType, N> {
  576. private:
  577. using Base = array_base<T, SizeType, N>;
  578. public:
  579. array()
  580. : Base() {
  581. }
  582. array(array<T, N> const& _other)
  583. : Base(_other) {
  584. }
  585. array(Base const& _other)
  586. : Base(_other) {
  587. }
  588. array(T* _data, SizeType const* _sz)
  589. : Base(_data, _sz) {
  590. }
  591. };
  592. // Specialize on char_T (row vector) for better support on strings.
  593. template <>
  594. class array<char_T, 2> : public array_base<char_T, SizeType, 2> {
  595. private:
  596. using Base = array_base<char_T, SizeType, 2>;
  597. public:
  598. array()
  599. : array_base() {
  600. }
  601. array(array<char_T, 2> const& _other)
  602. : Base(_other) {
  603. }
  604. array(Base const& _other)
  605. : Base(_other) {
  606. }
  607. array(std::string const& _str) {
  608. operator=(_str);
  609. }
  610. array(char_T const* const _str) {
  611. operator=(_str);
  612. }
  613. array(std::vector<char_T> const& _vec) {
  614. SizeType const n{static_cast<SizeType>(_vec.size())};
  615. set_size(1, n);
  616. data_.copy(&_vec[0], n);
  617. }
  618. array& operator=(std::string const& _str) {
  619. SizeType const n{static_cast<SizeType>(_str.size())};
  620. set_size(1, n);
  621. data_.copy(_str.c_str(), n);
  622. return *this;
  623. }
  624. array& operator=(char_T const* const _str) {
  625. SizeType const n{static_cast<SizeType>(strlen(_str))};
  626. set_size(1, n);
  627. data_.copy(_str, n);
  628. return *this;
  629. }
  630. operator std::string() const {
  631. return std::string(static_cast<char const*>(&(*this)[0]), static_cast<int>(size(1)));
  632. }
  633. };
  634. // Specialize on 2 dimensions for better support interactions with
  635. // std::vector and row vectors.
  636. template <typename T>
  637. class array<T, 2> : public array_base<T, SizeType, 2> {
  638. private:
  639. using Base = array_base<T, SizeType, 2>;
  640. public:
  641. array()
  642. : Base() {
  643. }
  644. array(array<T, 2> const& _other)
  645. : Base(_other) {
  646. }
  647. array(Base const& _other)
  648. : Base(_other) {
  649. }
  650. array(std::vector<T> const& _vec) {
  651. operator=(_vec);
  652. }
  653. array& operator=(std::vector<T> const& _vec) {
  654. SizeType n{static_cast<SizeType>(_vec.size())};
  655. Base::set_size(1, n);
  656. Base::data_.copy(&_vec[0], n);
  657. return *this;
  658. }
  659. operator std::vector<T>() const {
  660. T const* p{&Base::data_[0]};
  661. return std::vector<T>(p, p + Base::numel());
  662. }
  663. };
  664. // Specialize on 1 dimension for better support with std::vector and
  665. // column vectors.
  666. template <typename T>
  667. class array<T, 1> : public array_base<T, SizeType, 1> {
  668. private:
  669. using Base = array_base<T, SizeType, 1>;
  670. public:
  671. array()
  672. : Base() {
  673. }
  674. array(array<T, 1> const& _other)
  675. : Base(_other) {
  676. }
  677. array(Base const& _other)
  678. : Base(_other) {
  679. }
  680. array(std::vector<T> const& _vec) {
  681. operator=(_vec);
  682. }
  683. array& operator=(std::vector<T> const& _vec) {
  684. SizeType n{static_cast<SizeType>(_vec.size())};
  685. Base::set_size(n);
  686. Base::data_.copy(&_vec[0], n);
  687. return *this;
  688. }
  689. operator std::vector<T>() const {
  690. T const* p{&Base::data_[0]};
  691. return std::vector<T>(p, p + Base::numel());
  692. }
  693. };
  694. } // namespace coder
  695. #endif