Commit 741111a8 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Removed unused explicit const-specializations of SharedPointer

The compiler itself takes care of the problem by doing the right thing
in the problematic methods and not allowing to modify the
const-qualified data.
parent 5fa062f4
Loading
Loading
Loading
Loading
+4 −348
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@

#pragma once

#include <utility>
#include <TNL/Devices/Host.h>
#include <TNL/Devices/Cuda.h>
#include <TNL/SmartPointer.h>
@@ -51,8 +50,7 @@ namespace TNL {
 */
template< typename Object,
          typename Device = typename Object::DeviceType,
          bool lazy = false,
          bool isConst = std::is_const< Object >::value >
          bool lazy = false >
class SharedPointer
{
   static_assert( ! std::is_same< Device, void >::value, "The device cannot be void. You need to specify the device explicitly in your code." );
@@ -62,14 +60,13 @@ class SharedPointer
 * Non-const specialization
 */
template< typename Object, bool lazy >
class SharedPointer< Object, Devices::Host, lazy, false > : public SmartPointer
class SharedPointer< Object, Devices::Host, lazy > : public SmartPointer
{   
   public:
      
      typedef Object ObjectType;
      typedef Devices::Host DeviceType;
      typedef SharedPointer< Object, Devices::Host, lazy, false > ThisType;
      typedef SharedPointer< const Object, Devices::Host, lazy, true > ConstThisType;
      typedef SharedPointer< Object, Devices::Host, lazy > ThisType;
         
      template< typename... Args >
      explicit  SharedPointer( Args... args )
@@ -207,155 +204,11 @@ class SharedPointer< Object, Devices::Host, lazy, false > : public SmartPointer
      int* counter;
};

/****
 * Const specialization
 */
template< typename Object, bool lazy >
class SharedPointer< Object, Devices::Host, lazy, true > : public SmartPointer
{   
   public:
      
      typedef Object ObjectType;
      typedef Devices::Host DeviceType;
      typedef SharedPointer< Object, Devices::Host, lazy, true > ThisType;
      typedef typename std::remove_const< Object >::type NonConstObjectType;
         
      template< typename... Args >
      explicit  SharedPointer( Args... args )
      : counter( 0 ), pointer( 0 )
      {
         if( ! lazy )
         {
            this->counter = new int( 1 );
            this->pointer = new Object( args... );
         }
      }
      
      SharedPointer( const ThisType& pointer )
      : pointer( pointer.pointer ),
        counter( pointer.counter )
      {
         *counter += 1;
      }
      
      SharedPointer( const SharedPointer< NonConstObjectType, Devices::Host, lazy >& pointer )
      : pointer( pointer.pointer ),
        counter( pointer.counter )
      {
         *counter += 1;
      }

      
      template< typename... Args >
      bool recreate( Args... args )
      {         
         if( ! this->counter )
         {
            this->counter = new int( 1 );
            this->pointer = new ObjectType( args... );
            return true;
         }
         if( *this->counter == 1 )
         {
            /****
             * The object is not shared
             */
            this->pointer->~ObjectType();
            new ( this->pointer ) ObjectType( args... );
            return true;
         }
         ( *this->counter )--;
         this->pointer = new Object( args... );
         this->counter = new int( 1 );
         if( ! this->pointer || ! this->counter )
            return false;
         return true;         
      }      
      
      const Object* operator->() const
      {
         return this->pointer;
      }
            
      const Object& operator *() const
      {
         return *( this->pointer );
      }
      
      template< typename Device = Devices::Host >
      __cuda_callable__
      const Object& getData() const
      {
         return *( this->pointer );
      }
      
      const ThisType& operator=( const SharedPointer< NonConstObjectType, Devices::Host >& ptr )
      {
         this->free();
         this->pointer = ptr.pointer;
         this->counter = ptr.counter;
         *( this->counter ) += 1;
         return *this;
      }      

      
      const ThisType& operator=( const ThisType& ptr )
      {
         this->free();
         this->pointer = ptr.pointer;
         this->counter = ptr.counter;
         *( this->counter ) += 1;
         return *this;
      }      
      
      const ThisType& operator=( const ThisType&& ptr )
      {
         this->free();
         this->pointer = ptr.pointer;
         ptr.pointer= NULL;
         this->counter = ptr.counter;
         ptr.counter = NULL;
         return *this;
      }
            
      bool synchronize()
      {
         return true;
      }
      
      ~SharedPointer()
      {
         this->free();
      }

      
   protected:
      
      void free()
      {
         if( this->counter )
         {
            if( ! --*( this->counter ) )
            {
               delete this->counter;
               this->counter = nullptr;
               if( this->pointer )
                  delete this->pointer;
            }
         }

      }
      
      const Object* pointer;
      
      int* counter;
};

/****
 * Non-const specialization for CUDA
 */
template< typename Object, bool lazy >
class SharedPointer< Object, Devices::Cuda, lazy, false > : public SmartPointer
class SharedPointer< Object, Devices::Cuda, lazy > : public SmartPointer
{
   public:
      
@@ -590,201 +443,4 @@ class SharedPointer< Object, Devices::Cuda, lazy, false > : public SmartPointer
      int* counter;
};


/****
 * Const specialization for CUDA
 */
template< typename Object, bool lazy >
class SharedPointer< Object, Devices::Cuda, lazy, true > : public SmartPointer
{
   public:
      
      typedef Object ObjectType;
      typedef Devices::Host DeviceType;
      typedef SharedPointer< Object, Devices::Cuda, lazy > ThisType;
      typedef typename std::remove_const< Object >::type NonConstObjectType;      

      template< typename... Args >
      explicit  SharedPointer( Args... args )
      : counter( 0 ), cuda_pointer( 0 ), 
        pointer( 0 ), modified( false )
      {
         if( ! lazy )
         {
            this->counter = new int( 1 );
            this->pointer = new Object( args... );
#ifdef HAVE_CUDA         
            this->cuda_pointer = Devices::Cuda::passToDevice( *this->pointer );
            if( ! this->cuda_pointer )
               return;
            Devices::Cuda::insertSmartPointer( this );
#endif            
         }
      }
                  
      SharedPointer( const ThisType& pointer )
      : pointer( pointer.pointer ),
        cuda_pointer( pointer.cuda_pointer ),
        counter( pointer.counter ),
        modified( pointer.modified )
      {
         *counter += 1;
      }
      
      SharedPointer( const SharedPointer< NonConstObjectType, Devices::Cuda, lazy >& pointer )
      : pointer( pointer.pointer ),
        cuda_pointer( pointer.cuda_pointer ),
        counter( pointer.counter )
      {
         *counter += 1;
      }      

      template< typename... Args >
      bool recreate( Args... args )
      {
         if( ! this->counter )
         {
            this->counter = new int( 1 );
            this->pointer = new ObjectType( args... );
#ifdef HAVE_CUDA         
            this->cuda_pointer = Devices::Cuda::passToDevice( *this->pointer );
            if( ! this->cuda_pointer )
               return false;
            Devices::Cuda::insertSmartPointer( this );
#endif                 
            return true;
         }
         if( *this->counter == 1 )
         {
            /****
             * The object is not shared
             */
            this->pointer->~ObjectType();
            new ( this->pointer ) ObjectType( args... );
#ifdef HAVE_CUDA                     
            cudaMemcpy( this->cuda_pointer, this->pointer, sizeof( Object ), cudaMemcpyHostToDevice );
#endif            
            return true;
         }

         this->modified = false;
         this->counter= new int( 1 );
         this->pointer = new Object( args... );
         if( ! this->pointer || ! this->counter )
            return false;
#ifdef HAVE_CUDA         
         this->cuda_pointer = Devices::Cuda::passToDevice( *this->pointer );
         if( ! this->cuda_pointer )
            return false;
         Devices::Cuda::insertSmartPointer( this );
#endif
         return true;
      }
      
      const Object* operator->() const
      {
         return this->pointer;
      }
      
      const Object& operator *() const
      {
         return *( this->pointer );
      }
      
      template< typename Device = Devices::Host >   
      __cuda_callable__
      const Object& getData() const
      {
         static_assert( std::is_same< Device, Devices::Host >::value || std::is_same< Device, Devices::Cuda >::value, "Only Devices::Host or Devices::Cuda devices are accepted here." );
         Assert( this->pointer, );
         Assert( this->cuda_pointer, );
         if( std::is_same< Device, Devices::Host >::value )
            return *( this->pointer );
         if( std::is_same< Device, Devices::Cuda >::value )
            return *( this->cuda_pointer );            
      }

      
      /*const ThisType& operator=( ThisType&& ptr )
      {
         this->free();
#ifdef HAVE_CUDA
         if( this->cuda_pointer )
            cudaFree( this->cuda_pointer );
#endif                  
         this->pointer = ptr.pointer;
         this->cuda_pointer = ptr.cuda_pointer;
         this->modified = ptr.modified;
         this->counter = ptr.counter;
         ptr.pointer= NULL;
         ptr.cuda_pointer = NULL;
         ptr.modified = false;
         ptr.counter = NULL;
         return *this;
      }*/

      const ThisType& operator=( const SharedPointer< NonConstObjectType, Devices::Cuda >& ptr )
      {
         this->free();
         this->pointer = ptr.pointer;
         this->counter = ptr.counter;
         this->cuda_pointer = ptr.cuda_pointer;
         this->modified = ptr.modified;
         *( this->counter ) += 1;
         return *this;
      }      
      
      const ThisType& operator=( const ThisType& ptr )
      {
         this->free();
         this->pointer = ptr.pointer;
         this->cuda_pointer = ptr.cuda_pointer;
         this->modified = ptr.modified;
         this->counter = ptr.counter;
         *( this->counter ) += 1;
         return *this;
      }      
      
      bool synchronize()
      {
         return true;
      }
            
      ~SharedPointer()
      {
         this->free();
#ifdef HAVE_CUDA         
         Devices::Cuda::removeSmartPointer( this );
#endif         
      }
      
   protected:
      
      void free()
      {
         if( this->counter )
         {
            if( ! --*( this->counter ) )
            {
               delete this->counter;
               this->counter = nullptr;
               if( this->pointer )
                  delete this->pointer;
#ifdef HAVE_CUDA
               if( this->cuda_pointer )
                  cudaFree( this->cuda_pointer );
               checkCudaDevice;
#endif         
            }
         }
         
      }
      
      Object *pointer, *cuda_pointer;
      
      bool modified;
      
      int* counter;
};

} // namespace TNL