Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Register
    • Login

    SortedArray - bug or user mistake

    SDK Help
    0
    3
    535
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 23/03/2018 at 04:59, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   R19 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      Hi,

      I was playing around with the SortedArray, writing a little helper class to sort Int32 values

        
      class SortedInt32Array : public maxon::SortedArray<SortedInt32Array, maxon::BaseArray<Int32>>  
      {  
      public:  
        SortedInt32Array() {}  
          
        static inline maxon::Bool LessThan(Int32 a, Int32 b)    { return a < b; }  
        static inline maxon::Bool IsEqual(Int32 a, Int32 b)    { return a == b; }  
        static void InitInsertData(Int32& initme, const Int32& key) { initme = key; }  
      };  
      
        
      void SortInt32(const maxon::BaseArray<Int32>& numbers)  
      {  
        SortedInt32Array sorted;  
        for (const Int32& nbr : numbers)  
        {  
            maxon::Bool inserted;  
            Int32* item = sorted.FindOrInsert(nbr, inserted);  
            if (inserted)  
            {  
                // why do I need following line, shouldn't this be part of FindOrInsert implementation ???  
                sorted.InitInsertData(*item, nbr);   
            }  
        }  
        
      // some more ...  
      }  
        
      

      If I don't provide a call to sorted.InitInsertData() the value actually inserted into sorted is a zero, and I end up with sorted being a list of zeros.

      When I am looking at the actual SortedArray implementation

        
        template <typename SEARCH> T* FindOrInsert(const SEARCH& key, const T* ptr = nullptr)  
        {  
            CheckSort();  
            BaseSort<MYSELF> sort;  
            Int insertIdx = NOTOK;  
            T*    e = sort.FindInsertionIndex(key, _array, insertIdx);  
            if (!e)  
            {  
                e = _array.Insert(insertIdx);  
                if (e)  
                    MYSELF::InitInsertData(*e, key);  
            }  
            return e;  
        }  
        
        template <typename SEARCH> T* FindOrInsert(const SEARCH& key, Bool& newElement, const T* ptr = nullptr)  
        {  
            CheckSort();  
            BaseSort<MYSELF> sort;  
            Int insertIdx = NOTOK;  
            T*    e = sort.FindInsertionIndex(key, _array, insertIdx);  
            if (!e)  
            {  
                e = _array.Insert(insertIdx);  
                newElement = true;  
            }  
            else  
            {  
                newElement = false;  
            }  
            return e;  
        }  
      

      I notice that the function

        
      [T](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#ad3a1bd799977d25c6e2f36919a4b25bd) * [FindOrInsert](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#a5356f3c1132c7dd74218374f6bec26fe) (const SEARCH &key, const [T](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#ad3a1bd799977d25c6e2f36919a4b25bd) *ptr=[nullptr](https://developers.maxon.net/docs/cpp/2023_2/compilerdetection_8h.html#ac3c36c503cc2ba5594bb924b009713fc))  
      

      does actually perform a MYSELF::InitInsertData(*e, key);
      while function

        
      [T](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#ad3a1bd799977d25c6e2f36919a4b25bd) * [FindOrInsert](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#a630e3073602651759e7418541f2a2b64) (const SEARCH &key, [Bool](https://developers.maxon.net/docs/cpp/2023_2/namespacemaxon.html#a76a8b016e5ad61faf9062cc387df5016) &newElement, const [T](https://developers.maxon.net/docs/cpp/2023_2/classmaxon_1_1_sorted_array.html#ad3a1bd799977d25c6e2f36919a4b25bd) *ptr=[nullptr](https://developers.maxon.net/docs/cpp/2023_2/compilerdetection_8h.html#ac3c36c503cc2ba5594bb924b009713fc))  
      

      does not, while I would expect both function would perform a MYSELF::InitInsertData right after the item was inserted into the array.

      Am I missing something from the documentation, that as a user I should perform the InitInsertData after using the second function, but not when calling the first function ???

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 26/03/2018 at 08:45, xxxxxxxx wrote:

        Hi,

        after discussion with development this seems to be intentional. Of course then the documentation is a bit misleading and needs a fix.
        The FindOrInsert() with three parameters expects the value to be filled in after return.

        The developer suggested a shorter and more efficient implementation:

        void SortInt32(const maxon::BaseArray<Int32>& numbers)
        {
            SortedInt32Array sorted;
            Bool res = sorted.CopyFrom(numbers);
            if (!res)
                // handle error...
        }
        

        With this implementation there's also no need for InitInsertData().

        Or to make use of SimpleSort class, if sorting the array once is sufficient:

            SimpleSort<Int32> sort;
            sort.Sort(numbers); // with numbers again being a BaseArray<Int32>
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 26/03/2018 at 12:12, xxxxxxxx wrote:

          Thanks for the info, Andreas.

          I made a copy/paste mistake when providing my sort method to describe the problem.
          Where I originally had put the "// some more" outside of the "if (inserted)", I actually intended to have it inside.
          Hence the shorter suggestion from developer (while still a useful example) isn't really of use here.

            
          void SortInt32(const maxon::BaseArray<Int32>& numbers)  
          {  
            SortedInt32Array sorted;  
            for (const Int32& nbr : numbers)  
            {  
                maxon::Bool inserted;  
                Int32* item = sorted.FindOrInsert(nbr, inserted);  
                if (inserted)  
                {  
                    // why do I need following line, shouldn't this be part of FindOrInsert implementation ???  
                    sorted.InitInsertData(*item, nbr);  
            
                    // some more ... [intended]  
                }  
            }  
            
            // some more ... [original]  
          }  
            
          

          I guess, I could simply do a FindValue, and if not found, perform a FindOrInsert with 2 parameters (instead of the one with 3)

          Daniel

          1 Reply Last reply Reply Quote 0
          • First post
            Last post