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.

144 lines
4.7 KiB

Changed the way of looking up NETINFO_ITEM using net names (using boost::unordered_map). Added a hash function (wxString) for that. Introduced NETINFO_ITEM::GetNetItem( wxString ). BOARD::FindNet() uses the map. Net codes are updated upon net list update. (BOARD::ReplaceNetlist()) Added in some places (mostly class_board.cpp) pad->SetNet() calls to synchronize net codes. On creation of NETINFO_LIST, the first NETINFO_ITEM is added (the unconnected items net). Removed COMPONENT_NET::m_netNumber, as it was not used anywhere. Added an assert to D_PAD::GetNetname(), checking if net code and net name is consistent for unconnected pads. Added an assert for NETINFO_LIST::AppendNet() to assure that appended nets are unique. It seems that at this point: - Updating net lists works fine. The only difference between the file ouput is that after changes it contains empty nets as well. - Nets are not saved in the lexical order. Still, net names and net codes are properly assigned to all items in the .kicad_pcb file. It is going to be addressed in the next commit. I believe it should not create any problems, as pads are sorted by their net names anyway (NETINFO_LIST::buildPadsFullList()) Performed tests: - Created a blank PCB, saved as pic_programmer.kicad_pcb (from demos folder). Updated net lists. .kicad_pcb file (comparing to the results from master branch) differ with net order (as mentioned before), net codes and timestamps. - Removed some of components from the above .kicad_pcb file and updated net lists. Modules reappeared. .kicad_pcb file differs in the same way as described above. - Trying to change a pad net name (via properties dialog) results in assert being fired. It is done on purpose (as there is a call to GetNetname() and net name and net code do not match). This will not happen after the next commit. - Prepared a simple project (starting with schematics). Imported net list, changed schematic, reimported net list - changes are applied. - Eagle & KiCad legacy boards seem to load without any problem.
12 years ago
  1. #ifndef HASHTABLES_H_
  2. #define HASHTABLES_H_
  3. /*
  4. * This program source code file is part of KiCad, a free EDA CAD application.
  5. *
  6. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  7. * Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version 2
  12. * of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, you may find one here:
  21. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  22. * or you may search the http://www.gnu.org website for the version 2 license,
  23. * or you may write to the Free Software Foundation, Inc.,
  24. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  25. */
  26. #include <base_struct.h>
  27. #include <wx/string.h>
  28. // Three strategies for providing a portable hashtable are given.
  29. // C++, boost, and wx, in that order. C++ solution is no good for mingw.
  30. // So boost seems best for all platforms.
  31. #if 0 // C++ std::unordered_map, maybe in the future
  32. #include <unordered_map>
  33. /// Map a C string to an integer. Used in DSNLEXER.
  34. typedef std::unordered_map< std::string, int > KEYWORD_MAP;
  35. /// Map a C string to an EDA_RECT.
  36. /// The key is the classname of the derived wxformbuilder dialog.
  37. typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP;
  38. #elif 1 // boost::unordered_map
  39. // fix a compile bug at line 97 of boost/detail/container_fwd.hpp
  40. #define BOOST_DETAIL_TEST_FORCE_CONTAINER_FWD
  41. #include <boost/unordered_map.hpp>
  42. // see http://www.boost.org/doc/libs/1_49_0/doc/html/boost/unordered_map.html
  43. /// Equality test for "const char*" type used in very specialized KEYWORD_MAP below
  44. struct iequal_to : std::binary_function< const char*, const char*, bool >
  45. {
  46. bool operator()( const char* x, const char* y ) const
  47. {
  48. return !strcmp( x, y );
  49. }
  50. };
  51. /// Very fast and efficient hash function for "const char*" type, used in specialized
  52. /// KEYWORD_MAP below.
  53. /// taken from: http://www.boost.org/doc/libs/1_53_0/libs/unordered/examples/fnv1.hpp
  54. struct fnv_1a
  55. {
  56. /* not used, std::string is too slow:
  57. std::size_t operator()( std::string const& text ) const
  58. {
  59. std::size_t hash = 2166136261u;
  60. for( std::string::const_iterator it = text.begin(), end = text.end();
  61. it != end; ++it )
  62. {
  63. hash ^= *it;
  64. hash *= 16777619;
  65. }
  66. return hash;
  67. }
  68. */
  69. std::size_t operator()( const char* it ) const
  70. {
  71. std::size_t hash = 2166136261u;
  72. for( ; *it; ++it )
  73. {
  74. hash ^= (unsigned char) *it;
  75. hash *= 16777619;
  76. }
  77. return hash;
  78. }
  79. };
  80. /// Hash function for wxString, counterpart of std::string hash
  81. struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
  82. {
  83. std::size_t operator()( const wxString& aString ) const
  84. {
  85. std::size_t hash = 2166136261u;
  86. for( wxString::const_iterator it = aString.begin(); it != aString.end(); ++it )
  87. {
  88. hash ^= (unsigned char) *it;
  89. hash *= 16777619;
  90. }
  91. return hash;
  92. }
  93. };
  94. /**
  95. * Type KEYWORD_MAP
  96. * is a hashtable made of a const char* and an int. Note that use of this
  97. * type outside very specific circumstances is foolish since there is no storage
  98. * provided for the actual C string itself. This type assumes use with type KEYWORD
  99. * that is created by CMake and that table creates *constant* storage for C strings
  100. * (and pointers to those C strings). Here we are only interested in the C strings
  101. * themselves and only the pointers are duplicated within the hashtable.
  102. * If the strings were not constant and fixed, this type would not work.
  103. * Also note that normally a hashtable (i.e. unordered_map) using a const char* key
  104. * would simply compare the 32 bit or 64 bit pointers themselves, rather than
  105. * the C strings which they are known to point to in this context.
  106. * I force the latter behavior by supplying both "hash" and "equality" overloads
  107. * to the hashtable (unordered_map) template.
  108. * @author Dick Hollenbeck
  109. */
  110. typedef boost::unordered_map< const char*, int, fnv_1a, iequal_to > KEYWORD_MAP;
  111. /// Map a std::string to an EDA_RECT.
  112. /// The key is the classname of the derived wxformbuilder dialog.
  113. typedef boost::unordered_map< std::string, EDA_RECT > RECT_MAP;
  114. #endif
  115. #endif // HASHTABLES_H_