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

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6927
  • 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: 6927
  • 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: 3253
  • !false...it's funny 'cause it's true!
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 :)
Debugging:
Being the detective in a crime movie where you're also the murderer.

“Someone's sitting in the shade today because someone planted a tree a long time ago.”
- Warren Buffet

It's Alive!

  • BricsCAD
  • Needs a day job
  • Posts: 6927
  • AKA Daniel
Re: std::unique_ptr for DB objects... or bad idea
« Reply #3 on: May 25, 2019, 12:18:23 AM »
I’ve 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: 6927
  • 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: 3253
  • !false...it's funny 'cause it's true!
Re: std::unique_ptr for DB objects... or bad idea
« Reply #5 on: May 25, 2019, 12:23:41 AM »
toight :)
Debugging:
Being the detective in a crime movie where you're also the murderer.

“Someone's sitting in the shade today because someone planted a tree a long time ago.”
- Warren Buffet