text: /** Map/Dictionary support for int key and int value.
   *
   * @file
   * @author      bernhard-thiele, tbeu
   * @since       2012-12-22
   * @copyright see Modelica_DeviceDrivers project's License.txt file
   *
   * @note 2012-12-22: Provided function *not* (yet) used anywhere (except unit testing).
  */
  
  #ifndef MDDMAPINTINT_H_
  #define MDDMAPINTINT_H_
  
  #include <stdlib.h>
  
  #include "ModelicaUtilities.h"
  
  #define uthash_fatal(msg) ModelicaFormatMessage("Error: %s\n", msg); break
  #include "../../thirdParty/uthash/uthash.h"
  
  typedef struct MapIntInt {
      int first;
      int second;
      UT_hash_handle hh; /* Hashable structure */
  } MapIntInt;
  
  void* MDD_mapIntIntConstructor() {
      MapIntInt** mapIntInt = (MapIntInt**) malloc(sizeof(MapIntInt*));
      if (mapIntInt) {
          *mapIntInt = NULL;
      }
      return (void*) mapIntInt;
  }
  
  void MDD_mapIntIntDestructor(void* p_mapIntInt) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          MapIntInt* m;
          MapIntInt* tmp;
          HASH_ITER(hh, *mapIntInt, m, tmp) {
              HASH_DEL(*mapIntInt, m);
              free(m);
          }
          free(mapIntInt);
      }
  }
  
  void MDD_mapIntIntInsert(void* p_mapIntInt, int key, int value) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          MapIntInt* m;
          HASH_FIND_INT(*mapIntInt, &key, m);
          if (!m) {
              m = (MapIntInt*) malloc(sizeof(MapIntInt));
              if (m) {
                  m->first = key;
                  m->second = value;
                  HASH_ADD_INT(*mapIntInt, first, m);
              }
          }
          else {
              m->second = value;
          }
      }
  }
  
  int MDD_mapIntIntCount(void*p_mapIntInt, int key) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          MapIntInt* m;
          HASH_FIND_INT(*mapIntInt, &key, m);
          return m ? 1 : 0;
      }
      return 0;
  }
  
  int MDD_mapIntIntLookup(void* p_mapIntInt, int key) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          MapIntInt* m;
          HASH_FIND_INT(*mapIntInt, &key, m);
          if (!m) {
              ModelicaFormatError("MDD_mapIntIntLookup: Key '%d' not found\n", key);
          }
          return m->second;
      }
      ModelicaFormatError("MDD_mapIntIntLookup: Key '%d' not found\n", key);
      return 0;
  }
  
  int MDD_mapIntIntSize(void* p_mapIntInt) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          return (int) HASH_COUNT(*mapIntInt);
      }
      return 0;
  }
  
  void MDD_mapIntIntGetKeys(void* p_mapIntInt, int keys[]) {
      MapIntInt** mapIntInt = (MapIntInt**) p_mapIntInt;
      if (mapIntInt) {
          MapIntInt* m;
          MapIntInt* tmp;
          int i = 0;
          HASH_ITER(hh, *mapIntInt, m, tmp) {
              keys[i] = m->first;
              i++;
          }
      }
  }
  
  #endif /* MDDMAPINTINT_H_ */
  