
#include <QxPrecompiled.h>

#include <QxCollection/QxCollection.h>
#include <QxCollection/QxCollectionIterator.h>
#include <QxMemLeak/mem_leak.h>

namespace qx
{

   IxCollection::~IxCollection() = default;

   namespace unit_test
   {

      // Compilation option '_QX_HASH_NO_STD_NAMESPACE'
      // Try to avoid compilation error, something like : error: no matching function for call to 'qHash(const std::tuple<...>&)'
      // This is due to C++ ADL to resolve specialized functions : qHash(T) should be implemented in the same namespace as T
      // For 'std' classes, it should be NOT allowed : the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std
      // More details here : https://www.kdab.com/how-to-declare-a-qhash-overload/
      // And here : https://stackoverflow.com/questions/47460098/using-standard-library-types-as-keys-in-qhash-or-qset
      void qx_collection_unit_test()
      {
         // Test basic functionality with simple types
         {
            QxCollection<QString, QString *> coll;
            QxCollectionIterator<QString, QString *> itr(coll);
            coll.sortByKey();
            coll.sortByValue();
            itr.toFirst();
         }

         // Test with std::tuple as key
         {
            using type_std_tuple = std::tuple<QString, std::string, int>;
            QxCollection<type_std_tuple, std::shared_ptr<QWidget>> coll;
            coll.begin();
            coll.reserve(10);
            coll.clear();
            coll.count();
            coll.empty();

            type_std_tuple item = std::make_tuple(QString(), std::string(), 1);
            coll.contains(item);
         }

         // Test with std::pair as key
         {
            using type_std_pair = std::pair<QString, std::string>;
            QxCollection<type_std_pair, std::shared_ptr<QWidget>> coll;
            coll.begin();
            coll.reserve(10);
            coll.clear();
            coll.count();
            coll.empty();

            type_std_pair item = std::make_pair(QString(), std::string("1"));
            coll.contains(item);
         }

         // Test with QPair as key
         {
            using type_qt_pair = QPair<QDateTime, std::string>;
            QxCollection<type_qt_pair, std::shared_ptr<QWidget>> coll;
            coll.begin();
            coll.reserve(10);
            coll.clear();
            coll.count();
            coll.empty();

            type_qt_pair item = qMakePair(QDateTime(), std::string("1"));
            coll.contains(item);
         }

#ifdef _QX_ENABLE_BOOST
         // Test with boost::tuple as key
         {
            using type_boost_tuple = boost::tuple<QString, std::string, int>;
            QxCollection<type_boost_tuple, std::shared_ptr<QWidget>> coll;
            coll.begin();
            coll.reserve(10);
            coll.clear();
            coll.count();
            coll.empty();

            type_boost_tuple item = boost::make_tuple(QString(), std::string(), 1);
            coll.contains(item);
         }
#endif // _QX_ENABLE_BOOST
      }

   } // namespace unit_test
} // namespace qx
