xmasked_view.hpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /***************************************************************************
  2. * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
  3. * Copyright (c) QuantStack *
  4. * *
  5. * Distributed under the terms of the BSD 3-Clause License. *
  6. * *
  7. * The full license is in the file LICENSE, distributed with this software. *
  8. ****************************************************************************/
  9. #ifndef XTENSOR_XMASKED_VIEW_HPP
  10. #define XTENSOR_XMASKED_VIEW_HPP
  11. #include "xaccessible.hpp"
  12. #include "xexpression.hpp"
  13. #include "xiterable.hpp"
  14. #include "xsemantic.hpp"
  15. #include "xshape.hpp"
  16. #include "xtensor_forward.hpp"
  17. #include "xtl/xmasked_value.hpp"
  18. #include "xutils.hpp"
  19. namespace xt
  20. {
  21. /****************************
  22. * xmasked_view declaration *
  23. *****************************/
  24. template <class CTD, class CTM>
  25. class xmasked_view;
  26. template <class D, bool is_const>
  27. class xmasked_view_stepper;
  28. template <class T>
  29. struct xcontainer_inner_types;
  30. template <class CTD, class CTM>
  31. struct xcontainer_inner_types<xmasked_view<CTD, CTM>>
  32. {
  33. using data_type = std::decay_t<CTD>;
  34. using mask_type = std::decay_t<CTM>;
  35. using base_value_type = typename data_type::value_type;
  36. using flag_type = typename mask_type::value_type;
  37. using val_reference = inner_reference_t<CTD>;
  38. using mask_reference = inner_reference_t<CTM>;
  39. using value_type = xtl::xmasked_value<base_value_type, flag_type>;
  40. using reference = xtl::xmasked_value<val_reference, mask_reference>;
  41. using const_reference = xtl::xmasked_value<typename data_type::const_reference, typename mask_type::const_reference>;
  42. using size_type = typename data_type::size_type;
  43. using temporary_type = xarray<xtl::xmasked_value<base_value_type, flag_type>>;
  44. };
  45. template <class CTD, class CTM>
  46. struct xiterable_inner_types<xmasked_view<CTD, CTM>>
  47. {
  48. using masked_view_type = xmasked_view<CTD, CTM>;
  49. using inner_shape_type = typename std::decay_t<CTD>::inner_shape_type;
  50. using stepper = xmasked_view_stepper<masked_view_type, false>;
  51. using const_stepper = xmasked_view_stepper<masked_view_type, true>;
  52. };
  53. /**
  54. * @class xmasked_view
  55. * @brief View on an xoptional_assembly or xoptional_assembly_adaptor
  56. * hiding values depending on a given mask.
  57. *
  58. * The xmasked_view class implements a view on an xoptional_assembly or
  59. * xoptional_assembly_adaptor, it takes this xoptional_assembly and a
  60. * mask as input. The mask is an xexpression containing boolean values,
  61. * whenever the value of the mask is false, the optional value of
  62. * xmasked_view is considered missing, otherwise it depends on the
  63. * underlying xoptional_assembly.
  64. *
  65. * @tparam CTD The type of expression holding the values.
  66. * @tparam CTM The type of expression holding the mask.
  67. */
  68. template <class CTD, class CTM>
  69. class xmasked_view : public xview_semantic<xmasked_view<CTD, CTM>>,
  70. private xaccessible<xmasked_view<CTD, CTM>>,
  71. private xiterable<xmasked_view<CTD, CTM>>
  72. {
  73. public:
  74. using self_type = xmasked_view<CTD, CTM>;
  75. using semantic_base = xview_semantic<xmasked_view<CTD, CTM>>;
  76. using accessible_base = xaccessible<self_type>;
  77. using inner_types = xcontainer_inner_types<self_type>;
  78. using temporary_type = typename inner_types::temporary_type;
  79. using data_type = typename inner_types::data_type;
  80. using mask_type = typename inner_types::mask_type;
  81. using value_expression = CTD;
  82. using mask_expression = CTM;
  83. static constexpr bool is_data_const = std::is_const<std::remove_reference_t<value_expression>>::value;
  84. using base_value_type = typename inner_types::base_value_type;
  85. using base_reference = typename data_type::reference;
  86. using base_const_reference = typename data_type::const_reference;
  87. using flag_type = typename inner_types::flag_type;
  88. using flag_reference = typename mask_type::reference;
  89. using flag_const_reference = typename mask_type::const_reference;
  90. using val_reference = typename inner_types::val_reference;
  91. using mask_reference = typename inner_types::mask_reference;
  92. using value_type = typename inner_types::value_type;
  93. using reference = typename inner_types::reference;
  94. using const_reference = typename inner_types::const_reference;
  95. using pointer = xtl::xclosure_pointer<reference>;
  96. using const_pointer = xtl::xclosure_pointer<const_reference>;
  97. using size_type = typename inner_types::size_type;
  98. using difference_type = typename data_type::difference_type;
  99. using bool_load_type = xtl::xmasked_value<typename data_type::bool_load_type, mask_type>;
  100. using shape_type = typename data_type::shape_type;
  101. using strides_type = typename data_type::strides_type;
  102. static constexpr layout_type static_layout = data_type::static_layout;
  103. static constexpr bool contiguous_layout = false;
  104. using inner_shape_type = typename data_type::inner_shape_type;
  105. using inner_strides_type = typename data_type::inner_strides_type;
  106. using inner_backstrides_type = typename data_type::inner_backstrides_type;
  107. using expression_tag = xtensor_expression_tag;
  108. using iterable_base = xiterable<xmasked_view<CTD, CTM>>;
  109. using stepper = typename iterable_base::stepper;
  110. using const_stepper = typename iterable_base::const_stepper;
  111. template <layout_type L>
  112. using layout_iterator = typename iterable_base::template layout_iterator<L>;
  113. template <layout_type L>
  114. using const_layout_iterator = typename iterable_base::template const_layout_iterator<L>;
  115. template <layout_type L>
  116. using reverse_layout_iterator = typename iterable_base::template reverse_layout_iterator<L>;
  117. template <layout_type L>
  118. using const_reverse_layout_iterator = typename iterable_base::template const_reverse_layout_iterator<L>;
  119. template <class S, layout_type L>
  120. using broadcast_iterator = typename iterable_base::template broadcast_iterator<S, L>;
  121. template <class S, layout_type L>
  122. using const_broadcast_iterator = typename iterable_base::template const_broadcast_iterator<S, L>;
  123. template <class S, layout_type L>
  124. using reverse_broadcast_iterator = typename iterable_base::template reverse_broadcast_iterator<S, L>;
  125. template <class S, layout_type L>
  126. using const_reverse_broadcast_iterator = typename iterable_base::template const_reverse_broadcast_iterator<S, L>;
  127. using iterator = typename iterable_base::iterator;
  128. using const_iterator = typename iterable_base::const_iterator;
  129. using reverse_iterator = typename iterable_base::reverse_iterator;
  130. using const_reverse_iterator = typename iterable_base::const_reverse_iterator;
  131. template <class D, class M>
  132. xmasked_view(D&& data, M&& mask);
  133. xmasked_view(const xmasked_view&) = default;
  134. size_type size() const noexcept;
  135. const inner_shape_type& shape() const noexcept;
  136. const inner_strides_type& strides() const noexcept;
  137. const inner_backstrides_type& backstrides() const noexcept;
  138. using accessible_base::dimension;
  139. using accessible_base::shape;
  140. layout_type layout() const noexcept;
  141. bool is_contiguous() const noexcept;
  142. template <class T>
  143. void fill(const T& value);
  144. template <class... Args>
  145. reference operator()(Args... args);
  146. template <class... Args>
  147. const_reference operator()(Args... args) const;
  148. template <class... Args>
  149. reference unchecked(Args... args);
  150. template <class... Args>
  151. const_reference unchecked(Args... args) const;
  152. using accessible_base::at;
  153. using accessible_base::operator[];
  154. using accessible_base::back;
  155. using accessible_base::front;
  156. using accessible_base::in_bounds;
  157. using accessible_base::periodic;
  158. template <class It>
  159. reference element(It first, It last);
  160. template <class It>
  161. const_reference element(It first, It last) const;
  162. template <class S>
  163. bool has_linear_assign(const S& strides) const noexcept;
  164. data_type& value() noexcept;
  165. const data_type& value() const noexcept;
  166. mask_type& visible() noexcept;
  167. const mask_type& visible() const noexcept;
  168. using iterable_base::begin;
  169. using iterable_base::cbegin;
  170. using iterable_base::cend;
  171. using iterable_base::crbegin;
  172. using iterable_base::crend;
  173. using iterable_base::end;
  174. using iterable_base::rbegin;
  175. using iterable_base::rend;
  176. template <class S>
  177. stepper stepper_begin(const S& shape) noexcept;
  178. template <class S>
  179. stepper stepper_end(const S& shape, layout_type l) noexcept;
  180. template <class S>
  181. const_stepper stepper_begin(const S& shape) const noexcept;
  182. template <class S>
  183. const_stepper stepper_end(const S& shape, layout_type l) const noexcept;
  184. self_type& operator=(const self_type& rhs);
  185. template <class E>
  186. self_type& operator=(const xexpression<E>& e);
  187. template <class E>
  188. disable_xexpression<E, self_type>& operator=(const E& e);
  189. private:
  190. CTD m_data;
  191. CTM m_mask;
  192. void assign_temporary_impl(temporary_type&& tmp);
  193. friend class xiterable<self_type>;
  194. friend class xconst_iterable<self_type>;
  195. friend class xview_semantic<self_type>;
  196. friend class xaccessible<self_type>;
  197. friend class xconst_accessible<self_type>;
  198. };
  199. template <class D, bool is_const>
  200. class xmasked_view_stepper
  201. {
  202. public:
  203. using self_type = xmasked_view_stepper<D, is_const>;
  204. using masked_view_type = std::decay_t<D>;
  205. using value_type = typename masked_view_type::value_type;
  206. using reference = std::
  207. conditional_t<is_const, typename masked_view_type::const_reference, typename masked_view_type::reference>;
  208. using pointer = std::
  209. conditional_t<is_const, typename masked_view_type::const_pointer, typename masked_view_type::pointer>;
  210. using size_type = typename masked_view_type::size_type;
  211. using difference_type = typename masked_view_type::difference_type;
  212. using data_type = typename masked_view_type::data_type;
  213. using mask_type = typename masked_view_type::mask_type;
  214. using value_stepper = std::conditional_t<is_const, typename data_type::const_stepper, typename data_type::stepper>;
  215. using mask_stepper = std::conditional_t<is_const, typename mask_type::const_stepper, typename mask_type::stepper>;
  216. xmasked_view_stepper(value_stepper vs, mask_stepper fs) noexcept;
  217. void step(size_type dim);
  218. void step_back(size_type dim);
  219. void step(size_type dim, size_type n);
  220. void step_back(size_type dim, size_type n);
  221. void reset(size_type dim);
  222. void reset_back(size_type dim);
  223. void to_begin();
  224. void to_end(layout_type l);
  225. reference operator*() const;
  226. private:
  227. value_stepper m_vs;
  228. mask_stepper m_ms;
  229. };
  230. /*******************************
  231. * xmasked_view implementation *
  232. *******************************/
  233. /**
  234. * @name Constructors
  235. */
  236. //@{
  237. /**
  238. * Creates an xmasked_view, given the xoptional_assembly or
  239. * xoptional_assembly_adaptor and the mask
  240. *
  241. * @param data the underlying xoptional_assembly or xoptional_assembly_adaptor
  242. * @param mask the mask.
  243. */
  244. template <class CTD, class CTM>
  245. template <class D, class M>
  246. inline xmasked_view<CTD, CTM>::xmasked_view(D&& data, M&& mask)
  247. : m_data(std::forward<D>(data))
  248. , m_mask(std::forward<M>(mask))
  249. {
  250. }
  251. /**
  252. * @name Size and shape
  253. */
  254. //@{
  255. /**
  256. * Returns the number of elements in the xmasked_view.
  257. */
  258. template <class CTD, class CTM>
  259. inline auto xmasked_view<CTD, CTM>::size() const noexcept -> size_type
  260. {
  261. return m_data.size();
  262. }
  263. /**
  264. * Returns the shape of the xmasked_view.
  265. */
  266. template <class CTD, class CTM>
  267. inline auto xmasked_view<CTD, CTM>::shape() const noexcept -> const inner_shape_type&
  268. {
  269. return m_data.shape();
  270. }
  271. /**
  272. * Returns the strides of the xmasked_view.
  273. */
  274. template <class CTD, class CTM>
  275. inline auto xmasked_view<CTD, CTM>::strides() const noexcept -> const inner_strides_type&
  276. {
  277. return m_data.strides();
  278. }
  279. /**
  280. * Returns the backstrides of the xmasked_view.
  281. */
  282. template <class CTD, class CTM>
  283. inline auto xmasked_view<CTD, CTM>::backstrides() const noexcept -> const inner_backstrides_type&
  284. {
  285. return m_data.backstrides();
  286. }
  287. //@}
  288. /**
  289. * Return the layout_type of the xmasked_view
  290. * @return layout_type of the xmasked_view
  291. */
  292. template <class CTD, class CTM>
  293. inline layout_type xmasked_view<CTD, CTM>::layout() const noexcept
  294. {
  295. return m_data.layout();
  296. }
  297. template <class CTD, class CTM>
  298. inline bool xmasked_view<CTD, CTM>::is_contiguous() const noexcept
  299. {
  300. return false;
  301. }
  302. /**
  303. * Fills the data with the given value.
  304. * @param value the value to fill the data with.
  305. */
  306. template <class CTD, class CTM>
  307. template <class T>
  308. inline void xmasked_view<CTD, CTM>::fill(const T& value)
  309. {
  310. std::fill(this->begin(), this->end(), value);
  311. }
  312. /**
  313. * @name Data
  314. */
  315. //@{
  316. /**
  317. * Returns a reference to the element at the specified position in the xmasked_view.
  318. * @param args a list of indices specifying the position in the xmasked_view. Indices
  319. * must be unsigned integers, the number of indices should be equal or greater than
  320. * the number of dimensions of the xmasked_view.
  321. */
  322. template <class CTD, class CTM>
  323. template <class... Args>
  324. inline auto xmasked_view<CTD, CTM>::operator()(Args... args) -> reference
  325. {
  326. return reference(m_data(args...), m_mask(args...));
  327. }
  328. /**
  329. * Returns a constant reference to the element at the specified position in the xmasked_view.
  330. * @param args a list of indices specifying the position in the xmasked_view. Indices
  331. * must be unsigned integers, the number of indices should be equal or greater than
  332. * the number of dimensions of the xmasked_view.
  333. */
  334. template <class CTD, class CTM>
  335. template <class... Args>
  336. inline auto xmasked_view<CTD, CTM>::operator()(Args... args) const -> const_reference
  337. {
  338. return const_reference(m_data(args...), m_mask(args...));
  339. }
  340. /**
  341. * Returns a reference to the element at the specified position in the xmasked_view.
  342. * @param args a list of indices specifying the position in the xmasked_view. Indices
  343. * must be unsigned integers, the number of indices must be equal to the number of
  344. * dimensions of the xmasked_view, else the behavior is undefined.
  345. *
  346. * @warning This method is meant for performance, for expressions with a dynamic
  347. * number of dimensions (i.e. not known at compile time). Since it may have
  348. * undefined behavior (see parameters), operator() should be preferred whenever
  349. * it is possible.
  350. * @warning This method is NOT compatible with broadcasting, meaning the following
  351. * code has undefined behavior:
  352. * @code{.cpp}
  353. * xt::xarray<double> a = {{0, 1}, {2, 3}};
  354. * xt::xarray<double> b = {0, 1};
  355. * auto fd = a + b;
  356. * double res = fd.uncheked(0, 1);
  357. * @endcode
  358. */
  359. template <class CTD, class CTM>
  360. template <class... Args>
  361. inline auto xmasked_view<CTD, CTM>::unchecked(Args... args) -> reference
  362. {
  363. return reference(m_data.unchecked(args...), m_mask.unchecked(args...));
  364. }
  365. /**
  366. * Returns a constant reference to the element at the specified position in the xmasked_view.
  367. * @param args a list of indices specifying the position in the xmasked_view. Indices
  368. * must be unsigned integers, the number of indices must be equal to the number of
  369. * dimensions of the xmasked_view, else the behavior is undefined.
  370. *
  371. * @warning This method is meant for performance, for expressions with a dynamic
  372. * number of dimensions (i.e. not known at compile time). Since it may have
  373. * undefined behavior (see parameters), operator() should be preferred whenever
  374. * it is possible.
  375. * @warning This method is NOT compatible with broadcasting, meaning the following
  376. * code has undefined behavior:
  377. * @code{.cpp}
  378. * xt::xarray<double> a = {{0, 1}, {2, 3}};
  379. * xt::xarray<double> b = {0, 1};
  380. * auto fd = a + b;
  381. * double res = fd.uncheked(0, 1);
  382. * @endcode
  383. */
  384. template <class CTD, class CTM>
  385. template <class... Args>
  386. inline auto xmasked_view<CTD, CTM>::unchecked(Args... args) const -> const_reference
  387. {
  388. return const_reference(m_data.unchecked(args...), m_mask.unchecked(args...));
  389. }
  390. /**
  391. * Returns a reference to the element at the specified position in the xmasked_view.
  392. * @param first iterator starting the sequence of indices
  393. * @param last iterator ending the sequence of indices
  394. * The number of indices in the sequence should be equal to or greater
  395. * than the number of dimensions of the xmasked_view.
  396. */
  397. template <class CTD, class CTM>
  398. template <class It>
  399. inline auto xmasked_view<CTD, CTM>::element(It first, It last) -> reference
  400. {
  401. return reference(m_data.element(first, last), m_mask.element(first, last));
  402. }
  403. /**
  404. * Returns a constant reference to the element at the specified position in the xmasked_view.
  405. * @param first iterator starting the sequence of indices
  406. * @param last iterator ending the sequence of indices
  407. * The number of indices in the sequence should be equal to or greater
  408. * than the number of dimensions of the xmasked_view.
  409. */
  410. template <class CTD, class CTM>
  411. template <class It>
  412. inline auto xmasked_view<CTD, CTM>::element(It first, It last) const -> const_reference
  413. {
  414. return const_reference(m_data.element(first, last), m_mask.element(first, last));
  415. }
  416. //@}
  417. template <class CTD, class CTM>
  418. template <class S>
  419. inline bool xmasked_view<CTD, CTM>::has_linear_assign(const S& strides) const noexcept
  420. {
  421. return m_data.has_linear_assign(strides) && m_mask.has_linear_assign(strides);
  422. }
  423. /**
  424. * Return an expression for the values of the xmasked_view.
  425. */
  426. template <class CTD, class CTM>
  427. inline auto xmasked_view<CTD, CTM>::value() noexcept -> data_type&
  428. {
  429. return m_data;
  430. }
  431. /**
  432. * Return a constant expression for the values of the xmasked_view.
  433. */
  434. template <class CTD, class CTM>
  435. inline auto xmasked_view<CTD, CTM>::value() const noexcept -> const data_type&
  436. {
  437. return m_data;
  438. }
  439. /**
  440. * Return an expression for the mask of the xmasked_view.
  441. */
  442. template <class CTD, class CTM>
  443. inline auto xmasked_view<CTD, CTM>::visible() noexcept -> mask_type&
  444. {
  445. return m_mask;
  446. }
  447. /**
  448. * Return a constant expression for the mask of the xmasked_view.
  449. */
  450. template <class CTD, class CTM>
  451. inline auto xmasked_view<CTD, CTM>::visible() const noexcept -> const mask_type&
  452. {
  453. return m_mask;
  454. }
  455. template <class CTD, class CTM>
  456. template <class S>
  457. inline auto xmasked_view<CTD, CTM>::stepper_begin(const S& shape) noexcept -> stepper
  458. {
  459. return stepper(value().stepper_begin(shape), visible().stepper_begin(shape));
  460. }
  461. template <class CTD, class CTM>
  462. template <class S>
  463. inline auto xmasked_view<CTD, CTM>::stepper_end(const S& shape, layout_type l) noexcept -> stepper
  464. {
  465. return stepper(value().stepper_end(shape, l), visible().stepper_end(shape, l));
  466. }
  467. template <class CTD, class CTM>
  468. template <class S>
  469. inline auto xmasked_view<CTD, CTM>::stepper_begin(const S& shape) const noexcept -> const_stepper
  470. {
  471. return const_stepper(value().stepper_begin(shape), visible().stepper_begin(shape));
  472. }
  473. template <class CTD, class CTM>
  474. template <class S>
  475. inline auto xmasked_view<CTD, CTM>::stepper_end(const S& shape, layout_type l) const noexcept
  476. -> const_stepper
  477. {
  478. return const_stepper(value().stepper_end(shape, l), visible().stepper_end(shape, l));
  479. }
  480. template <class CTD, class CTM>
  481. inline auto xmasked_view<CTD, CTM>::operator=(const self_type& rhs) -> self_type&
  482. {
  483. temporary_type tmp(rhs);
  484. return this->assign_temporary(std::move(tmp));
  485. }
  486. template <class CTD, class CTM>
  487. template <class E>
  488. inline auto xmasked_view<CTD, CTM>::operator=(const xexpression<E>& e) -> self_type&
  489. {
  490. return semantic_base::operator=(e);
  491. }
  492. template <class CTD, class CTM>
  493. template <class E>
  494. inline auto xmasked_view<CTD, CTM>::operator=(const E& e) -> disable_xexpression<E, self_type>&
  495. {
  496. std::fill(this->begin(), this->end(), e);
  497. return *this;
  498. }
  499. template <class CTD, class CTM>
  500. inline void xmasked_view<CTD, CTM>::assign_temporary_impl(temporary_type&& tmp)
  501. {
  502. std::copy(tmp.cbegin(), tmp.cend(), this->begin());
  503. }
  504. template <class CTD, class CTM>
  505. inline xmasked_view<CTD, CTM> masked_view(CTD&& data, CTM&& mask)
  506. {
  507. return xmasked_view<CTD, CTM>(std::forward<CTD>(data), std::forward<CTM>(mask));
  508. }
  509. /***************************************
  510. * xmasked_view_stepper implementation *
  511. ***************************************/
  512. template <class D, bool C>
  513. inline xmasked_view_stepper<D, C>::xmasked_view_stepper(value_stepper vs, mask_stepper ms) noexcept
  514. : m_vs(vs)
  515. , m_ms(ms)
  516. {
  517. }
  518. template <class D, bool C>
  519. inline void xmasked_view_stepper<D, C>::step(size_type dim)
  520. {
  521. m_vs.step(dim);
  522. m_ms.step(dim);
  523. }
  524. template <class D, bool C>
  525. inline void xmasked_view_stepper<D, C>::step_back(size_type dim)
  526. {
  527. m_vs.step_back(dim);
  528. m_ms.step_back(dim);
  529. }
  530. template <class D, bool C>
  531. inline void xmasked_view_stepper<D, C>::step(size_type dim, size_type n)
  532. {
  533. m_vs.step(dim, n);
  534. m_ms.step(dim, n);
  535. }
  536. template <class D, bool C>
  537. inline void xmasked_view_stepper<D, C>::step_back(size_type dim, size_type n)
  538. {
  539. m_vs.step_back(dim, n);
  540. m_ms.step_back(dim, n);
  541. }
  542. template <class D, bool C>
  543. inline void xmasked_view_stepper<D, C>::reset(size_type dim)
  544. {
  545. m_vs.reset(dim);
  546. m_ms.reset(dim);
  547. }
  548. template <class D, bool C>
  549. inline void xmasked_view_stepper<D, C>::reset_back(size_type dim)
  550. {
  551. m_vs.reset_back(dim);
  552. m_ms.reset_back(dim);
  553. }
  554. template <class D, bool C>
  555. inline void xmasked_view_stepper<D, C>::to_begin()
  556. {
  557. m_vs.to_begin();
  558. m_ms.to_begin();
  559. }
  560. template <class D, bool C>
  561. inline void xmasked_view_stepper<D, C>::to_end(layout_type l)
  562. {
  563. m_vs.to_end(l);
  564. m_ms.to_end(l);
  565. }
  566. template <class D, bool C>
  567. inline auto xmasked_view_stepper<D, C>::operator*() const -> reference
  568. {
  569. return reference(*m_vs, *m_ms);
  570. }
  571. }
  572. #endif