@@ -281,7 +281,16 @@ struct SConstant<CDenseVector<SCALAR>> {
281281 }
282282};
283283
284- // ! \brief Decorates an Eigen::Map of a dense matrix with some useful methods.
284+ // ! \brief Decorates an Eigen::Map of a dense matrix with some useful methods
285+ // ! and changes default copy semantics to shallow copy.
286+ // !
287+ // ! IMPLEMENTATION:\n
288+ // ! This effectively acts like a std::reference_wrapper of an Eigen::Map for
289+ // ! an Eigen matrix. In particular, all copying is shallow unlike Eigen::Map
290+ // ! that acts directly on the referenced memory. This is to match the behaviour
291+ // ! of CMemoryMappedDenseVector.
292+ // !
293+ // ! \sa CMemoryMappedDenseVector for more information.
285294template <typename SCALAR>
286295class CMemoryMappedDenseMatrix
287296 : public Eigen::Map<typename CDenseMatrix<SCALAR>::TBase> {
@@ -302,11 +311,32 @@ class CMemoryMappedDenseMatrix
302311 CMemoryMappedDenseMatrix (CMemoryMappedDenseMatrix& other)
303312 : CMemoryMappedDenseMatrix{static_cast <const CMemoryMappedDenseMatrix&>(other)} {}
304313 CMemoryMappedDenseMatrix (const CMemoryMappedDenseMatrix& other)
305- : TBase{static_cast <const TBase&>(other)} {}
306- CMemoryMappedDenseMatrix (CMemoryMappedDenseMatrix&& other) = default ;
307- CMemoryMappedDenseMatrix& operator =(const CMemoryMappedDenseMatrix& other) = default ;
308- CMemoryMappedDenseMatrix& operator =(CMemoryMappedDenseMatrix&& other) = default ;
314+ : TBase{nullptr , 1 , 1 } {
315+ this ->reseat (other);
316+ }
317+ CMemoryMappedDenseMatrix (CMemoryMappedDenseMatrix&& other)
318+ : TBase{nullptr , 1 , 1 } {
319+ this ->reseat (other);
320+ }
321+ CMemoryMappedDenseMatrix& operator =(const CMemoryMappedDenseMatrix& other) {
322+ if (this != &other) {
323+ this ->reseat (other);
324+ }
325+ return *this ;
326+ }
327+ CMemoryMappedDenseMatrix& operator =(CMemoryMappedDenseMatrix&& other) {
328+ if (this != &other) {
329+ this ->reseat (other);
330+ }
331+ return *this ;
332+ }
309333 // @}
334+
335+ private:
336+ void reseat (const CMemoryMappedDenseMatrix& other) {
337+ TBase* base{static_cast <TBase*>(this )};
338+ new (base) TBase{const_cast <SCALAR*>(other.data ()), other.rows (), other.cols ()};
339+ }
310340};
311341
312342// ! \brief Gets a constant square dense matrix with specified dimension or with
@@ -323,7 +353,37 @@ struct SConstant<CMemoryMappedDenseMatrix<SCALAR>> {
323353 }
324354};
325355
326- // ! \brief Decorates an Eigen::Map of a dense vector with some useful methods.
356+ // ! \brief Decorates an Eigen::Map of a dense vector with some useful methods
357+ // ! and changes default copy semantics to shallow.
358+ // !
359+ // ! IMPLEMENTATION:\n
360+ // ! This effectively acts like a std::reference_wrapper of an Eigen::Map for
361+ // ! an Eigen vector. In particular, all copying is shallow unlike Eigen::Map
362+ // ! that acts directly on the referenced memory, i.e.
363+ // ! \code{.cpp}
364+ // ! double values1[]{1.0, 1.0};
365+ // ! double values2[]{2.0, 2.0};
366+ // !
367+ // ! CMemoryMappedDenseVector<double> mm1{values1, 2};
368+ // ! CMemoryMappedDenseVector<double> mm2{values2, 2};
369+ // !
370+ // ! mm1 = mm2;
371+ // ! std::cout << mm1(0) << "," << mm1(1) << "," << values1[0] << "," << values1[1] << std::endl;
372+ // !
373+ // ! Eigen::Map<Eigen::VectorXd> map1{values1, 2};
374+ // ! Eigen::Map<Eigen::VectorXd> map2{values2, 2};
375+ // !
376+ // ! map1 = map2;
377+ // ! std::cout << map1(0) << "," << map1(1) << "," << values1[0] << "," << values1[1] << std::endl;
378+ // ! \endcode
379+ // !
380+ // ! Outputs:\n
381+ // ! 2,2,1,1\n
382+ // ! 2,2,2,2
383+ // !
384+ // ! This better fits our needs with data frames where we want to reference the
385+ // ! memory stored in the data frame rows, but never modify it directly through
386+ // ! this vector type.
327387template <typename SCALAR>
328388class CMemoryMappedDenseVector
329389 : public Eigen::Map<typename CDenseVector<SCALAR>::TBase> {
@@ -337,17 +397,32 @@ class CMemoryMappedDenseVector
337397 // ! Forwarding constructor.
338398 template <typename ... ARGS>
339399 CMemoryMappedDenseVector (ARGS&&... args)
340- : TBase( std::forward<ARGS>(args)...) {}
400+ : TBase{ std::forward<ARGS>(args)...} {}
341401
342402 // ! \name Copy and Move Semantics
343403 // @{
344404 CMemoryMappedDenseVector (CMemoryMappedDenseVector& other)
345405 : CMemoryMappedDenseVector{static_cast <const CMemoryMappedDenseVector&>(other)} {}
346406 CMemoryMappedDenseVector (const CMemoryMappedDenseVector& other)
347- : TBase{static_cast <const TBase&>(other)} {}
348- CMemoryMappedDenseVector (CMemoryMappedDenseVector&& other) = default ;
349- CMemoryMappedDenseVector& operator =(const CMemoryMappedDenseVector& other) = default ;
350- CMemoryMappedDenseVector& operator =(CMemoryMappedDenseVector&& other) = default ;
407+ : TBase{nullptr , 1 } {
408+ this ->reseat (other);
409+ }
410+ CMemoryMappedDenseVector (CMemoryMappedDenseVector&& other)
411+ : TBase{nullptr , 1 } {
412+ this ->reseat (other);
413+ }
414+ CMemoryMappedDenseVector& operator =(const CMemoryMappedDenseVector& other) {
415+ if (this != &other) {
416+ this ->reseat (other);
417+ }
418+ return *this ;
419+ }
420+ CMemoryMappedDenseVector& operator =(CMemoryMappedDenseVector&& other) {
421+ if (this != &other) {
422+ this ->reseat (other);
423+ }
424+ return *this ;
425+ }
351426 // @}
352427
353428 // ! Get a checksum of this object.
@@ -357,6 +432,12 @@ class CMemoryMappedDenseVector
357432 }
358433 return seed;
359434 }
435+
436+ private:
437+ void reseat (const CMemoryMappedDenseVector& other) {
438+ TBase* base{static_cast <TBase*>(this )};
439+ new (base) TBase{const_cast <SCALAR*>(other.data ()), other.size ()};
440+ }
360441};
361442
362443// ! \brief Gets a constant dense vector with specified dimension.
0 commit comments