You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.6 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  5. * Copyright (C) 2012-2020 KiCad Developers, see AUTHORS.TXT for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef HASHTABLES_H_
  25. #define HASHTABLES_H_
  26. #include <unordered_map>
  27. #include <wx/string.h>
  28. // First some utility classes and functions
  29. /// Equality test for "const char*" type used in very specialized KEYWORD_MAP below
  30. struct iequal_to
  31. {
  32. bool operator()( const char* x, const char* y ) const
  33. {
  34. return !strcmp( x, y );
  35. }
  36. };
  37. /// Very fast and efficient hash function for "const char*" type, used in specialized
  38. /// KEYWORD_MAP below.
  39. /// taken from: http://www.boost.org/doc/libs/1_53_0/libs/unordered/examples/fnv1.hpp
  40. struct fnv_1a
  41. {
  42. std::size_t operator()( const char* it ) const
  43. {
  44. std::size_t hash = 2166136261u;
  45. for( ; *it; ++it )
  46. {
  47. hash ^= (unsigned char) *it;
  48. hash *= 16777619;
  49. }
  50. return hash;
  51. }
  52. };
  53. #ifdef SWIG
  54. /// Declare a std::unordered_map and also the swig %template in unison
  55. #define DECL_HASH_FOR_SWIG( TypeName, KeyType, ValueType ) \
  56. namespace std \
  57. { \
  58. % template( TypeName ) unordered_map<KeyType, ValueType>; \
  59. } \
  60. typedef std::unordered_map<KeyType, ValueType> TypeName;
  61. #else
  62. /// Declare a std::unordered_map but no swig %template
  63. #define DECL_HASH_FOR_SWIG( TypeName, KeyType, ValueType ) \
  64. typedef std::unordered_map<KeyType, ValueType> TypeName;
  65. #endif
  66. /**
  67. * A hashtable made of a const char* and an int.
  68. *
  69. * @note The use of this type outside very specific circumstances is foolish since there is
  70. * no storage provided for the actual C string itself.
  71. *
  72. * This type assumes use with type #KEYWORD that is created by CMake and that table creates
  73. * *constant* storage for C strings (and pointers to those C strings). Here we are only
  74. * interested in the C strings themselves and only the pointers are duplicated within the
  75. * hashtable. If the strings were not constant and fixed, this type would not work. Also
  76. * note that normally a hashtable (i.e. unordered_map) using a const char* key would simply
  77. * compare the 32 bit or 64 bit pointers themselves, rather than the C strings which they
  78. * are known to point to in this context. I force the latter behavior by supplying both
  79. * "hash" and "equality" overloads to the hashtable (unordered_map) template.
  80. *
  81. * @author Dick Hollenbeck
  82. */
  83. typedef std::unordered_map< const char*, int, fnv_1a, iequal_to > KEYWORD_MAP;
  84. #endif // HASHTABLES_H_