Author Topic: std::unique_ptr for DB objects... or bad idea  (Read 1563 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
std::unique_ptr for DB objects... or bad idea
« on: October 21, 2018, 12:09:55 AM »
std::unique_ptr for DB objects... or bad idea lol

Code - C++: [Select]
  1. template <class T>
  2. class DBObjectDeleter
  3. {
  4. public:
  5.     inline void operator()(T *p)
  6.     {
  7.         if (p != nullptr)
  8.             return this->close(p);
  9.     }
  10. private:
  11.     inline void close(T *p)
  12.     {
  13.         if (!p->objectId().isNull())
  14.             p->close();
  15.         else
  16.             this->deleter(p);
  17.     }
  18.     inline void deleter(T *p)
  19.     {
  20.         delete p;
  21.         p = nullptr;
  22.     }
  23. };
  24.  
  25. template<typename T>
  26. using unique_dbo_ptr = std::unique_ptr<T, DBObjectDeleter<T>>;
  27.  
  28. typedef unique_dbo_ptr<AcDbLine> AcDbLineUPtr;
  29.  

Code - C++: [Select]
  1.     void quaz()
  2.     {
  3.         AcDbLineUPtr pLine(new AcDbLine());
  4.         //...
  5.     }
  6.  

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: std::unique_ptr for DB objects... or bad idea
« Reply #1 on: October 21, 2018, 12:26:42 AM »
along the same lines

Code - C++: [Select]
  1. typedef std::unique_ptr<AcDbDictionaryIterator> AcDbDictionaryIteratorPtr;
  2. typedef std::unique_ptr<AcDbBlockTableIterator> AcDbBlockTableIteratorPtr;
  3. typedef std::unique_ptr<AcDbBlockTableRecordIterator> AcDbBlockTableRecordIteratorPtr;
  4.  
  5. inline AcDbBlockTableIteratorPtr createBlockTableIterator
  6. (
  7.     const AcDbBlockTable* pSrc,
  8.     Acad::ErrorStatus *stat = nullptr,
  9.     bool atBeginning = true,
  10.     bool skipDeleted = true
  11. )
  12. {
  13.     Acad::ErrorStatus _stat = eOk;
  14.     AcDbBlockTableIterator *pIter = nullptr;
  15.     if (pSrc != nullptr)
  16.         _stat = pSrc->newIterator(pIter, atBeginning, skipDeleted);
  17.     if (stat != nullptr)
  18.         *stat = _stat;
  19.     return AcDbBlockTableIteratorPtr(pIter);
  20. }
  21.  
  22. inline AcDbBlockTableRecordIteratorPtr createBlockTableRecordIterator
  23. (
  24.     const AcDbBlockTableRecord* pSrc,
  25.     Acad::ErrorStatus *stat = nullptr,
  26.     bool atBeginning = true,
  27.     bool skipDeleted = true
  28. )
  29. {
  30.     Acad::ErrorStatus _stat = eOk;
  31.     AcDbBlockTableRecordIterator *pIter = nullptr;
  32.     if (pSrc != nullptr)
  33.         _stat = pSrc->newIterator(pIter, atBeginning, skipDeleted);
  34.     if (stat != nullptr)
  35.         *stat = _stat;
  36.     return AcDbBlockTableRecordIteratorPtr(pIter);
  37. }
  38.  

Code - C++: [Select]
  1.    static void foo(void)
  2.     {
  3.         AcDbObjectId rid, id;
  4.         AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
  5.         AcDbBlockTablePointer pBT(pDb->blockTableId());
  6.         AcDbBlockTableIteratorPtr pBTIter = createBlockTableIterator(pBT);
  7.         for (pBTIter->start(); !pBTIter->done(); pBTIter->step())
  8.         {
  9.             if (pBTIter->getRecordId(rid) == eOk)
  10.             {
  11.                 AcDbBlockTableRecordPointer record(rid);
  12.                 AcDbBlockTableRecordIteratorPtr piter = createBlockTableRecordIterator(record);
  13.                 for (piter->start(); !piter->done(); piter->step())
  14.                 {
  15.                     if (piter->getEntityId(id) == eOk)
  16.                     {
  17.                         AcDbEntityPointer pEnt(id);
  18.                         //... yada yada
  19.                     }
  20.                 }
  21.             }
  22.         }
  23.     }
  24.  
« Last Edit: October 21, 2018, 12:44:36 AM by nullptr »

MickD

  • Gator
  • Posts: 3309
  • (x-in)->[process]->(y-out)
Re: std::unique_ptr for DB objects... or bad idea
« Reply #2 on: May 24, 2019, 07:08:55 PM »
Still brushing up on my C++ but when I first read about the new smart pointers this was the first place I thought about using them (i.e. in some ObjectARX).

I guess it depends on the size of your function and how many 'new' pointers you have to manage, then again they would be used quite a bit in many functions so I think yes, good idea :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: To attain knowledge, add things
every day; to obtain wisdom, remove things every day.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: std::unique_ptr for DB objects... or bad idea
« Reply #3 on: May 25, 2019, 12:18:23 AM »
Ive been using AcDbObjectPointer for dbobjects and std::unique_ptr for iterators (and everything else)

Code - C++: [Select]
  1. //
  2. template<typename IteratorType>
  3. constexpr auto makeIterator = [](const auto& record)
  4. {
  5.     IteratorType *pIter = nullptr;
  6.     Acad::ErrorStatus es = record.newIterator(pIter);
  7.     return std::make_tuple(es, std::unique_ptr<IteratorType>(pIter));
  8. };
  9. constexpr auto makeBlockTableIterator = makeIterator<AcDbBlockTableIterator>;
  10. constexpr auto makeBlockTableRecordIterator = makeIterator<AcDbBlockTableRecordIterator>;
  11.  
  12.  
  13. //
  14.    if (AcDbBlockTablePointer pBt(blockTableId, AcDb::kForRead); pBt.openStatus() == eOk)
  15.     {
  16.         if (auto[es, btTter] = makeBlockTableIterator(*pBt); es == eOk)
  17.         {
  18.             for (btTter->start(); !btTter->done(); btTter->step())
  19.             {
  20.                ...
  21.             }
  22.         }
  23.     }
  24.  

and I have been passing by refrence

Code - C++: [Select]
  1.  
  2.     void woohoo(AcDbObjectId id)
  3.     {
  4.         if (AcDbObjectPointer<AcDbLine> pLine(id); pLine.openStatus() == eOk)
  5.         {
  6.             yahoo(*pLine);
  7.         }
  8.     }
  9.  
  10.     Acad::ErrorStatus yahoo(AcDbLine& line)
  11.     {
  12.         AcString layer;
  13.         return line.layer(layer);
  14.     }
  15.  

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6941
  • AKA Daniel
Re: std::unique_ptr for DB objects... or bad idea
« Reply #4 on: May 25, 2019, 12:19:40 AM »
of course this may change in a few weeks  :lmao:

MickD

  • Gator
  • Posts: 3309
  • (x-in)->[process]->(y-out)
Re: std::unique_ptr for DB objects... or bad idea
« Reply #5 on: May 25, 2019, 12:23:41 AM »
toight :)
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: To attain knowledge, add things
every day; to obtain wisdom, remove things every day.