Listx.c

C:\home\SVGCats_src\src\Listx.c

[目次 | 関数]

目次

関数一覧


   1|/*************************************************************************
   2|*  1. <<< 単方向リスト構造 (ListX) >>> 
   3|**************************************************************************/
   4|
   5|#include "mixer_precomp.h"  /* Auto precompiled header, Look at mixer-... folder */
   6|// #pragma hdrstop
   7|
   8|#if defined(USES_MXP_AUTOINC)
   9| #include "listx.ah"  /* Auto include header, Look at mixer-... folder */
  10|#endif
  11| 
  12|/*-----------------------------------------------------------------------*/
  13|/*  2. <<< ◆(ListX) 単方向リスト構造・コンテナ >>> */ 
  14|/*-----------------------------------------------------------------------*/
  15|
  16|#ifdef  USES_SYM
  17|SYM_STRUCT_START( ListX )
  18|SYM_STRUCT_LOOP_FUNC( ListX, ListX_doLoopFunc )
  19|SYM_STRUCT_MEMB_FUNC( ListX, ListX_doReadMemb, NULL )  /* first */
  20|SYM_STRUCT_END( ListX )
  21|#endif
  22|
  23|
  24| 
  25|/*************************************************************************
  26|*  3. <<< [ListX_init_byAble_imp] ListX_init_byAble の関数部 >>> 
  27|**************************************************************************/
  28|#ifdef  USES_ARRX
  29|void  ListX_init_byAble_imp( ListX* m, ArrX_Able* able, Offset list_elem,
  30|  Offset able_elem, int elem_size )
  31|{
  32|  ListX_Builder  b;
  33|  char*  p = (char*)able->arr.first;
  34|  char*  p_over = (char*)able->arr.last;
  35|
  36|  b = ListX_initForBuilder( m );
  37|  while ( p < p_over ) {
  38|    if ( Offset_ref( able_elem, p, bool ) ) {
  39|
  40|      /* 以下は、ListX_Builder_add( &b, p ); に相当 */
  41|      **(&b) = p;
  42|      *(&b) = &Offset_ref( list_elem, p, ListX_Elem );
  43|    }
  44|    p += elem_size;
  45|  }
  46|  ListX_Builder_finish( &b );
  47|}
  48|#endif
  49| 
  50|/*************************************************************************
  51|*  4. <<< [ListX_init_byArrXBuf_imp] ListX_init_byArrXBuf の関数部分 >>> 
  52|**************************************************************************/
  53|#ifdef  USES_ARRX
  54|void  ListX_init_byArrXBuf_imp( ListX* m, ArrX_Buf* buf, Offset elem_list,
  55|  int elem_size )
  56|{
  57|  ListX_Builder  b;
  58|  char*  p = (char*)buf->first;
  59|  char*  p_over = (char*)buf->last;
  60|
  61|  b = ListX_initForBuilder( m );
  62|  while ( p < p_over ) {
  63|    ListX_Builder_add2( &b, p, elem_list );
  64|    p += elem_size;
  65|  }
  66|  ListX_Builder_finish( &b );
  67|}
  68|#endif
  69| 
  70|/*************************************************************************
  71|*  5. <<< [ListX_toEmptyDelete_imp] ListX_toEmptyDelete の関数部分 >>> 
  72|**************************************************************************/
  73|#ifdef USES_INF
  74|#ifdef LISTX_USE_MALLOC
  75|void  ListX_toEmptyDelete_imp( ListX* m, Offset elem_offset,
  76|  Inf_FinishFunc Elem_finish )
  77|{
  78|  void*  p;
  79|  void*  next;
  80|
  81|  if ( Elem_finish != NULL ) {
  82|    for ( p = m->first;  p != NULL;  p = next ) {
  83|      next = Offset_ref( elem_offset, p, ListX_Elem );
  84|      Elem_finish( p );
  85|      free( p );
  86|    }
  87|  }
  88|  else {
  89|    for ( p = m->first;  p != NULL;  p = next ) {
  90|      next = Offset_ref( elem_offset, p, ListX_Elem );
  91|      free( p );
  92|    }
  93|  }
  94|  ListX_toEmpty( m );
  95|}
  96|#endif  /* USES_INF */
  97|#endif
  98|
  99|
 100| 
 101|/*************************************************************************
 102|*  6. <<< [ListX_insert_imp] ListX_insert の関数部 >>> 
 103|**************************************************************************/
 104|void  ListX_insert_imp( ListX* m, void* pos, void* ins, Offset elem_next )
 105|{
 106|  void*  p;
 107|  void*  p_prev;
 108|
 109|  ASSERT( m != NULL );
 110|  ASSERT( m->first != NULL || ( m->first == NULL && pos == NULL ) );
 111|  ASSERT( ins != NULL );
 112|
 113|  /* 要素があって、先頭の場合と */
 114|  /* 要素が無くて、末尾の場合(先頭の ASSERT で pos == NULL) */
 115|  if ( m->first == pos || m->first == NULL )  {
 116|    Offset_ref( elem_next, ins, void* ) = m->first;
 117|    m->first = ins;
 118|  }
 119|
 120|  /* 先頭ではない場合 */
 121|  else {
 122|    p = Offset_ref( elem_next, m->first, void* );
 123|    p_prev = m->first;
 124|    for (;;) {
 125|      if ( p == pos ) {
 126|        Offset_ref( elem_next, ins, void* ) = p;
 127|        Offset_ref( elem_next, p_prev, void* ) = ins;
 128|        return;
 129|      }
 130|      ASSERT( p != NULL );  /* pos が見つからない */
 131|      p_prev = p;
 132|      p = Offset_ref( elem_next, p, void* );
 133|    }
 134|  }
 135|}
 136|
 137| 
 138|/*************************************************************************
 139|*  7. <<< [ListX_insertSet_imp] ListX_insertSet の関数部 >>> 
 140|**************************************************************************/
 141|void  ListX_insertSet_imp( ListX* m, void* pos, void* ins_first, Offset elem_next )
 142|{
 143|  void*  p;
 144|  void*  p_prev;
 145|  void*  ins_end;
 146|
 147|  ASSERT( m != NULL );
 148|  ASSERT( m->first != NULL || ( m->first == NULL && pos == NULL ) );
 149|  ASSERT( ins_first != NULL );
 150|
 151|  for ( ins_end = ins_first;  Offset_ref( elem_next, ins_end, void* ) != NULL;
 152|        ins_end = Offset_ref( elem_next, ins_end, void* ) );
 153|
 154|
 155|  /* 要素があって、先頭の場合と */
 156|  /* 要素が無くて、末尾の場合(先頭の ASSERT で pos == NULL) */
 157|  if ( m->first == pos || m->first == NULL )  {
 158|    Offset_ref( elem_next, ins_end, void* ) = m->first;
 159|    m->first = ins_first;
 160|  }
 161|
 162|  /* 先頭ではない場合 */
 163|  else {
 164|    p = Offset_ref( elem_next, m->first, void* );
 165|    p_prev = m->first;
 166|    for (;;) {
 167|      if ( p == pos ) {
 168|        Offset_ref( elem_next, ins_end, void* ) = p;
 169|        Offset_ref( elem_next, p_prev, void* ) = ins_first;
 170|        return;
 171|      }
 172|      ASSERT( p != NULL );  /* pos が見つからない */
 173|      p_prev = p;
 174|      p = Offset_ref( elem_next, p, void* );
 175|    }
 176|  }
 177|}
 178|
 179|
 180| 
 181|/*************************************************************************
 182|*  8. <<< [ListX_addFirstMalloc_imp] ListX_addFirstMalloc の実装部分 >>> 
 183|**************************************************************************/
 184|#ifdef LISTX_USE_MALLOC
 185|void*  ListX_addFirstMalloc_imp( ListX* m, Offset elem_offset, int size )
 186|{
 187|  void*  p = malloc( size );
 188|  Offset_ref( elem_offset, p, ListX_Elem ) = m->first;
 189|  m->first = p;
 190|  return  p;
 191|}
 192|#endif
 193| 
 194|/*************************************************************************
 195|*  9. <<< [ListX_insertMalloc_imp] ListX_insertMalloc の関数部分 >>> 
 196|**************************************************************************/
 197|#ifdef  LISTX_USE_MALLOC
 198|void*  ListX_insertMalloc_imp( ListX* m, void* pos, Offset elem_offset, int size )
 199|{
 200|  void*  obj = malloc( size );
 201|  ListX_insert_imp( m, pos, obj, elem_offset );
 202|  return  obj;
 203|}
 204|#endif
 205| 
 206|/*************************************************************************
 207|*  10. <<< [ListX_remove_imp] ListX_remove の関数部 >>> 
 208|**************************************************************************/
 209|void  ListX_remove_imp( ListX* m, void* elem, Offset elem_next )
 210|{
 211|  void*  p;
 212|  void*  p_prev;
 213|
 214|  ASSERT( m->first != NULL && elem != NULL );
 215|
 216|  /* 先頭の場合 */
 217|  if ( m->first == elem )  {
 218|    m->first = Offset_ref( elem_next, m->first, void* );
 219|  }
 220|  /* 先頭ではない場合 */
 221|  else {
 222|    p = Offset_ref( elem_next, m->first, void* );
 223|    p_prev = m->first;
 224|    for (;;) {
 225|      ASSERT( p != NULL );  /* 見つからない */
 226|      if ( p == elem ) {
 227|        Offset_ref( elem_next, p_prev, void* ) =
 228|          Offset_ref( elem_next, p, void* );
 229|        return;
 230|      }
 231|      p_prev = p;
 232|      p = Offset_ref( elem_next, p, void* );
 233|    }
 234|  }
 235|}
 236|
 237| 
 238|/*************************************************************************
 239|*  11. <<< [ListX_removeSet_imp] ListX_removeSet の関数部 >>> 
 240|**************************************************************************/
 241|void*  ListX_removeSet_imp( ListX* m, ListX_Elem* first, ListX_Elem* last, Offset elem_next )
 242|{
 243|  void*  p;
 244|  void*  p_prev;
 245|
 246|  ASSERT( ListX_getI_imp( m, first, elem_next ) >= 0 );
 247|  ASSERT( last == NULL || ListX_getI_imp( m, last, elem_next ) >= 0 );
 248|
 249|
 250|  /* 先頭の場合 */
 251|  if ( m->first == first )  {
 252|    m->first = ( last == NULL ? NULL : Offset_ref( elem_next, last, void* ) );
 253|  }
 254|  /* 先頭ではない場合 */
 255|  else {
 256|    p = Offset_ref( elem_next, m->first, void* );
 257|    p_prev = m->first;
 258|    for (;;) {
 259|      ASSERT( p != NULL );  /* 見つからない */
 260|      if ( p == first ) {
 261|        Offset_ref( elem_next, p_prev, void* ) =
 262|          ( last == NULL ? NULL : Offset_ref( elem_next, last, void* ) );
 263|        break;
 264|      }
 265|      p_prev = p;
 266|      p = Offset_ref( elem_next, p, void* );
 267|    }
 268|  }
 269|
 270|  /* 除外したリストの最後は NULL にする */
 271|  if ( last != NULL )  Offset_ref( elem_next, last, void* ) = NULL;
 272|
 273|
 274|  return  first;
 275|}
 276|
 277| 
 278|/*************************************************************************
 279|*  12. <<< [ListX_removeDeleteAfters_imp] ListX_removeDeleteAfters の関数部 >>> 
 280|**************************************************************************/
 281|void  ListX_removeDeleteAfters_imp( ListX* m, void* elem, Offset elem_offset,
 282|  Inf_FinishFunc type_finish )
 283|{
 284|  void*  next;
 285|  void*  prev;
 286|
 287|  prev = ListX_getPrev_imp( m, elem, elem_offset );
 288|  if ( prev == NULL )  m->first = NULL;
 289|  else  Offset_ref( elem_offset, prev, void* ) = NULL;
 290|
 291|  for ( next = elem;  next != NULL; ) {
 292|    prev = next;
 293|    next = Offset_ref( elem_offset, next, void* );
 294|    if ( type_finish != NULL )
 295|      StdPlus_delete( prev, type_finish );
 296|  }
 297|}
 298|
 299|
 300| 
 301|/*************************************************************************
 302|*  13. <<< [ListX_reverse_imp] ListX_reverse の関数部 >>> 
 303|**************************************************************************/
 304|void  ListX_reverse_imp( ListX* m, Offset ofs )
 305|{
 306|  ListX  newList;
 307|  void*  ptr;
 308|
 309|  newList.first = NULL;
 310|  ptr = m->first;
 311|  while ( ptr != NULL ) {
 312|    void*  next = Offset_ref( ofs, ptr, void* );
 313|    Offset_ref( ofs, ptr, void* ) = newList.first;
 314|    newList.first = ptr;
 315|    ptr = next;
 316|  }
 317|  m->first = newList.first;
 318|}
 319|
 320|
 321| 
 322|/*************************************************************************
 323|*  14. <<< [ListX_move_imp] ListX_move の関数部 >>> 
 324|**************************************************************************/
 325|void  ListX_move_imp( ListX* m, void* pos, void* moving, Offset elem_offset )
 326|{
 327|  if ( pos == moving )  return;
 328|  ListX_remove_imp( m, moving, elem_offset );
 329|  ListX_insert_imp( m, pos, moving, elem_offset );
 330|}
 331|
 332| 
 333|/*************************************************************************
 334|*  15. <<< [ListX_moveStep_imp] ListX_moveStep の関数部 >>> 
 335|**************************************************************************/
 336|void  ListX_moveStep_imp( ListX* m, void* moving, Offset elem_offset, int plus )
 337|{
 338|  void*  pos;
 339|  int    i;
 340|
 341|  i = ListX_getI_imp( m, moving, elem_offset );
 342|  ASSERT( i != -1 );
 343|
 344|  if ( plus <= 0 ) {
 345|    i += plus;
 346|    if ( i <= 0 )  pos = m->first;
 347|    else  pos = ListX_get_imp( m, i, elem_offset );
 348|  }
 349|  else {
 350|    i += plus + 1;
 351|    if ( i >= ListX_getN_imp( m, elem_offset ) )  pos = NULL;
 352|    else  pos = ListX_get_imp( m, i, elem_offset );
 353|  }
 354|
 355|  ListX_move_imp( m, pos, moving, elem_offset );
 356|}
 357|
 358| 
 359|/*************************************************************************
 360|*  16. <<< [ListX_moveSet_imp] ListX_moveSet の関数部 >>> 
 361|**************************************************************************/
 362|void  ListX_moveSet_imp( ListX* m, void* from_start, void* from_endNext,
 363|  void* to, Offset elem_offset )
 364|{
 365|  void*  start_prev = ListX_getPrev_imp( m, from_start, elem_offset );
 366|  void*  end_prev = ( from_endNext == NULL ) ?
 367|      ListX_getLast_imp( m, elem_offset ) :
 368|      ListX_getPrev_imp( m, from_endNext, elem_offset );
 369|  void*  to_prev = ( to == NULL ) ?
 370|      ListX_getLast_imp( m, elem_offset ) :
 371|      ListX_getPrev_imp( m, to, elem_offset );
 372|
 373|  if ( to == from_start || to == from_endNext )  return;
 374|
 375|  #ifndef  NDEBUG
 376|  {
 377|    void*  p;
 378|    bool   bStart = false;
 379|    bool   bEnd = false;
 380|    bool   bTo = false;
 381|
 382|    for ( p = m->first; p != NULL;
 383|          p = Offset_ref( elem_offset, p, void* ) ) {
 384|      if ( p == from_start )  bStart = true;
 385|      else if ( p == from_endNext && bStart )  bEnd = true;
 386|      else if ( p == to ) {
 387|        if ( ! bStart || bEnd )  bTo = true;
 388|      }
 389|    }
 390|    ASSERT( bStart );
 391|    ASSERT( bEnd || from_endNext == NULL );
 392|    ASSERT( bTo || to == NULL );
 393|  }
 394|  #endif
 395|
 396|  ASSERT( end_prev != NULL );
 397|  Offset_ref( elem_offset, end_prev, void* ) = to;
 398|
 399|  if ( to_prev == NULL )
 400|    m->first = from_start;
 401|  else
 402|    Offset_ref( elem_offset, to_prev, void* ) = from_start;
 403|
 404|  if ( start_prev == NULL )
 405|    m->first = from_endNext;
 406|  else
 407|    Offset_ref( elem_offset, start_prev, void* ) = from_endNext;
 408|}
 409|
 410| 
 411|/*************************************************************************
 412|*  17. <<< [ListX_getLast_imp] ListX_getLast の関数部 >>> 
 413|**************************************************************************/
 414|#ifdef  USES_OFFSET
 415|void*  ListX_getLast_imp( ListX* m, Offset elem_offset )
 416|{
 417|  void*  p = m->first;
 418|  void*  p2;
 419|
 420|  if ( p == NULL )  return  NULL;
 421|  for (;;) {
 422|    p2 = Offset_ref( elem_offset, p, void* );
 423|    if ( p2 == NULL )  break;
 424|    p = p2;
 425|  }
 426|
 427|  return  p;
 428|}
 429|#endif
 430|
 431| 
 432|/*************************************************************************
 433|*  18. <<< [ListX_get_imp] ListX_get の関数部 >>> 
 434|**************************************************************************/
 435|#ifdef  USES_OFFSET
 436|void*  ListX_get_imp( ListX* m, int i, Offset elem_offset )
 437|{
 438|  void*  p = m->first;
 439|
 440|  if ( i < 0 )  return  NULL;
 441|
 442|  while ( i > 0 ) {
 443|    if ( p == NULL )  return  NULL;
 444|    p = Offset_ref( elem_offset, p, void* );
 445|    i--;
 446|  }
 447|
 448|  return  p;
 449|}
 450|#endif
 451|
 452| 
 453|/*************************************************************************
 454|*  19. <<< [ListX_getI_imp] ListX_getI の関数部 >>> 
 455|**************************************************************************/
 456|int   ListX_getI_imp( ListX* m, void* elem, Offset elem_offset )
 457|{
 458|  int  i = 0;
 459|  void*  p = m->first;
 460|
 461|  while ( p != NULL ) {
 462|    if ( p == elem )  return  i;
 463|    p = Offset_ref( elem_offset, p, void* );
 464|    i++;
 465|  }
 466|
 467|  return  -1;
 468|}
 469| 
 470|/*************************************************************************
 471|*  20. <<< [ListX_getI2_imp] ListX_getI2 の関数部 >>> 
 472|**************************************************************************/
 473|int   ListX_getI2_imp( ListX* m, void* elem, Offset elem_offset )
 474|{
 475|  int  i = 0;
 476|  void*  p = m->first;
 477|
 478|  while ( p != NULL ) {
 479|    if ( p == elem )  return  i;
 480|    p = Offset_ref( elem_offset, p, void* );
 481|    i++;
 482|  }
 483|
 484|  return  i;
 485|}
 486| 
 487|/*************************************************************************
 488|*  21. <<< [ListX_getN_imp] ListX_getN の関数部 >>> 
 489|**************************************************************************/
 490|#ifdef  USES_OFFSET
 491|int  ListX_getN_imp( ListX* m, Offset elem_offset )
 492|{
 493|  int  i = 0;
 494|  void*  p = m->first;
 495|
 496|  while ( p != NULL ) {
 497|    p = Offset_ref( elem_offset, p, void* );
 498|    i++;
 499|  }
 500|
 501|  return  i;
 502|}
 503|#endif
 504|
 505| 
 506|/*************************************************************************
 507|*  22. <<< [ListX_getPrev_imp] ListX_getPrev の関数部 >>> 
 508|**************************************************************************/
 509|void*  ListX_getPrev_imp( ListX* m, void* elem, Offset elem_offset )
 510|{
 511|  void*  p;
 512|  void*  prev = NULL;
 513|
 514|  for ( ListX_forEach_imp( m, &p, elem_offset ) ) {
 515|    if ( p == elem )  break;
 516|    prev = p;
 517|  }
 518|  return  prev;
 519|}
 520|
 521| 
 522|/***********************************************************************
 523|*  23. <<< [ListX_search_s_imp] 検索する >>> 
 524|*【引数】
 525|*  ・Offset_Key*  key;     辞書要素のキー情報
 526|*  ・char*  kword;         検索するキー文字列
 527|*  ・Offset  elem_offset;  辞書要素の ListX_Elem 型抽象クラスのオフセット
 528|*  ・void*  返り値;        ヒットした辞書要素のアドレス(NULL=ヒットなし)
 529|************************************************************************/
 530|#ifndef  USES_MORI_STDLIB
 531|#ifdef  __STRING_H
 532|#if !defined(FOR_GHS) && !defined(FOR_CA) && !defined(FOR_WINCE)
 533|
 534|void*  ListX_search_s_imp( ListX* m, Offset_Key* key, const char* kword,
 535|  Offset elem_offset )
 536|{
 537|  void*  p;
 538|
 539|  for ( ListX_forEach_imp( m, &p, elem_offset ) ) {
 540|    if ( Offset_Key_isHit( key, p, kword ) )  return  p;
 541|  }
 542|  return  NULL;
 543|}
 544|
 545|#endif
 546|#endif
 547|#endif
 548|
 549|
 550|
 551|
 552|
 553| 
 554|/*************************************************************************
 555|*  24. <<< [ListX_printElem_imp] ListX_printElem の関数部 >>> 
 556|**************************************************************************/
 557|#ifndef  ERRORS_CUT_DEBUG_TOOL
 558|void  ListX_printElem_imp( ListX* m, Offset elem_offset, const char* title )
 559|{
 560|  int  i = 0;
 561|  ListX_Elem*  p;
 562|
 563|  Errors_printf( "%sListX(%p)...", title, m );
 564|  Errors_printf( "%s  first = %p", title, m->first );
 565|  for ( ListX_forEach_imp( m, &p, elem_offset ) ) {
 566|    Errors_printf( "%s  elem(%d).adr = %p", title, i, p );
 567|    i++;
 568|  }
 569|}
 570|#endif
 571|
 572| 
 573|/**************************************************************************
 574|*  25. <<< [ListX_doLoopFunc] SYM_STRUCT_LOOP_FUNC に指定する関数 >>> 
 575|***************************************************************************/
 576|#ifdef  USES_SYM
 577|bool  ListX_doLoopFunc( Sym_Ref* container, Sym_Ref* elem )
 578|{
 579|  ListX*  m;
 580|
 581|  if ( container->type == Sym_StructType )  m = (ListX*)container->adr;
 582|  else  m = *(ListX**)container->adr;
 583|
 584|  if ( elem->adr == NULL )  elem->adr = m->first;
 585|  else   elem->adr = Offset_ref( (Offset)container->elem_param, elem->adr, void* );
 586|
 587|  return  elem->adr != NULL;
 588|}
 589|#endif
 590|
 591| 
 592|/**************************************************************************
 593|*  26. <<< [ListX_doReadMemb] SYM_STRUCT_MEMB_FUNC に指定する関数 >>> 
 594|***************************************************************************/
 595|#ifdef  USES_SYM
 596|void  ListX_doReadMemb( Sym_Ref* obj, char* name, Sym_Ref* ret )
 597|{
 598|  ListX*  m = (ListX*)obj->adr;
 599|
 600|  if ( strcmp( name, "first" ) == 0 ) {
 601|    ret->adr = m->first;
 602|    ret->type = obj->elem_type;
 603|    ret->st = obj->elem_st;
 604|  }
 605|}
 606|#endif
 607|
 608| 
 609|/*-----------------------------------------------------------------------*/
 610|/*  27. <<< ◆(ListX_Adder) 単方向リスト構造・末尾追加子 >>> */ 
 611|/*-----------------------------------------------------------------------*/
 612|
 613|
 614| 
 615|/*************************************************************************
 616|*  28. <<< [ListX_Adder_init_imp] ListX_Adder_init の実装部 >>> 
 617|*【引数】
 618|*  ・ListX_Adder*  m;   単方向リスト構造・末尾追加子
 619|*  ・ListX*        list;   要素を追加されるリスト・コンテナ
 620|*  ・Offset     elemOfs;   リスト要素の ListX_Elem_extend へのオフセット
 621|**************************************************************************/
 622|#ifdef  USES_OFFSET
 623|void  ListX_Adder_init_imp( ListX_Adder* m, ListX* list, Offset elemOfs )
 624|{
 625|  *m = (ListX_Adder)list->first;
 626|  while ( *m != NULL ) {
 627|    *m = &Offset_ref( elemOfs, *m, void*);
 628|  }
 629|}
 630|#endif
 631|
 632| 
 633|/*-----------------------------------------------------------------------*/
 634|/*  29. <<< ◆(ListX_Dic) ハッシュテーブルを用いた辞書(ヒープ使用) >>> */ 
 635|/*-----------------------------------------------------------------------*/
 636|
 637|#ifdef  USES_INF
 638|#ifdef  USES_ARRX
 639|#ifdef  USES_STRX
 640|#ifdef  USES_STDPLUS
 641|#ifdef  LISTX_USE_MALLOC
 642| 
 643|/***********************************************************************
 644|*  30. <<< [ListX_Dic_init_imp] ListX_Dic_init の関数部分 >>> 
 645|************************************************************************/
 646|void  ListX_Dic_init_imp( ListX_Dic* m, int width, Offset_Key* key,
 647|  StrX_HashFunc hash, Offset ofsElem )
 648|{
 649|  int  size = sizeof( ListX_Plus ) * width;
 650|  void*  p = malloc( size );
 651|  ListX_Plus*  lp;
 652|
 653|  ArrX_init( &m->table, p, size );
 654|  for ( ArrX_forEach( &m->table, &lp, ListX_Plus ) ) {
 655|    ListX_Plus_init2( lp, ofsElem );
 656|  }
 657|  m->width = ArrX_getN( &m->table, ListX_Plus );
 658|  m->key = *key;
 659|  m->hash = hash;
 660|}
 661|
 662| 
 663|/***********************************************************************
 664|*  31. <<< [ListX_Dic_toEmpty_imp] ListX_Dic_toEmpty の関数部分 >>> 
 665|************************************************************************/
 666|void  ListX_Dic_toEmpty_imp( ListX_Dic* m, Offset elem_offset,
 667|  Inf_FinishFunc Elem_finish )
 668|{
 669|  ListX_Plus*  lp;
 670|
 671|  for ( ArrX_forEach( &m->table, &lp, ListX_Plus ) ) {
 672|    ListX_toEmptyDelete_imp( (ListX*)lp, elem_offset, Elem_finish );
 673|  }
 674|}
 675|
 676| 
 677|/***********************************************************************
 678|*  32. <<< [ListX_Dic_finish_imp] 後始末する >>> 
 679|************************************************************************/
 680|void   ListX_Dic_finish_imp( ListX_Dic* m, Offset elem_offset,
 681|  Inf_FinishFunc Elem_finish )
 682|{
 683|  ListX_Dic_toEmpty_imp( m, elem_offset, Elem_finish );
 684|  free( m->table.first );
 685|}
 686|
 687| 
 688|/***********************************************************************
 689|*  33. <<< [ListX_Dic_search_imp] ListX_Dic_search の関数部分 >>> 
 690|************************************************************************/
 691|#ifndef  USES_MORI_STDLIB
 692|#ifdef  __STRING_H
 693|#if !defined(FOR_GHS) && !defined(FOR_CA) && !defined(FOR_WINCE)
 694|
 695|void*  ListX_Dic_search_imp( ListX_Dic* m, const char* kword, Offset elem_offset )
 696|{
 697|  int  hashVar = m->hash( kword, m->width );
 698|
 699|  return  ListX_search_s_imp( (ListX*)ArrX_get( &m->table, hashVar, ListX_Plus ),
 700|    &m->key, kword, elem_offset );
 701|}
 702|
 703|#endif
 704|#endif
 705|#endif
 706|
 707| 
 708|/***********************************************************************
 709|*  34. <<< [ListX_Dic_searchNext_imp] ListX_Dic_searchNext の関数部分 >>> 
 710|************************************************************************/
 711|void*  ListX_Dic_searchNext_imp( ListX_Dic* m, void* prev, Offset ofsElem )
 712|{
 713|  /* ListX_Elem_forEachFrom */
 714|  Errors_notSupport();
 715|  return NULL;
 716|}
 717|
 718| 
 719|/**************************************************************************
 720|*  35. <<< [ListX_Dic_alloc_imp] ListX_Dic_alloc の関数部分 >>> 
 721|***************************************************************************/
 722|#ifndef  USES_MORI_STDLIB
 723|#ifdef  __STRING_H
 724|#if !defined(FOR_GHS) && !defined(FOR_CA) && !defined(FOR_WINCE)
 725|
 726|void*  ListX_Dic_alloc_imp( ListX_Dic* m, const char* kword,
 727|  Offset elem_offset, size_t elem_size )
 728|{
 729|  int  hashVar = m->hash( kword, m->width );
 730|  ListX_Plus*  list = ArrX_get( &m->table, hashVar, ListX_Plus );
 731|
 732|  if ( ListX_search_s_imp( (ListX*)list, &m->key, kword, elem_offset ) == NULL ) {
 733|    void*  p = malloc( elem_size );
 734|    ListX_Plus_addFirst( list, p );
 735|    return  p;
 736|  }
 737|  else
 738|    return  NULL;
 739|}
 740|
 741|#endif
 742|#endif
 743|#endif
 744|
 745|
 746| 
 747|/**************************************************************************
 748|*  36. <<< [ListX_Dic_getN] 辞書要素の数を返す >>> 
 749|***************************************************************************/
 750|int  ListX_Dic_getN( ListX_Dic* m )
 751|{
 752|  int  n = 0;
 753|  ListX_Plus*  lp;
 754|
 755|  for ( ArrX_forEach( &m->table, &lp, ListX_Plus ) ) {
 756|    n += ListX_getN_imp( (ListX*)lp, lp->next );
 757|  }
 758|  return  n;
 759|}
 760|
 761| 
 762|/**************************************************************************
 763|*  37. <<< [ListX_Dic_print] デバッグ表示する >>> 
 764|***************************************************************************/
 765|#ifndef  ERRORS_CUT_DEBUG_TOOL
 766|void  ListX_Dic_print( ListX_Dic* m, const char* title )
 767|{
 768|  Errors_printf( "%snElem = %d", title, ListX_Dic_getN( m ) );
 769|}
 770|#endif
 771|
 772| 
 773|#endif 
 774|#endif
 775|#endif
 776|#endif
 777|#endif
 778| 
 779|