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.

5578 lines
203 KiB

  1. #if !defined(sparsepp_h_guard_)
  2. #define sparsepp_h_guard_
  3. // ----------------------------------------------------------------------
  4. // Copyright (c) 2016, Gregory Popovitch - greg7mdp@gmail.com
  5. // All rights reserved.
  6. //
  7. // This work is derived from Google's sparsehash library
  8. //
  9. // Copyright (c) 2005, Google Inc.
  10. // All rights reserved.
  11. //
  12. // Redistribution and use in source and binary forms, with or without
  13. // modification, are permitted provided that the following conditions are
  14. // met:
  15. //
  16. // * Redistributions of source code must retain the above copyright
  17. // notice, this list of conditions and the following disclaimer.
  18. // * Redistributions in binary form must reproduce the above
  19. // copyright notice, this list of conditions and the following disclaimer
  20. // in the documentation and/or other materials provided with the
  21. // distribution.
  22. // * Neither the name of Google Inc. nor the names of its
  23. // contributors may be used to endorse or promote products derived from
  24. // this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  32. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  33. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  34. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. // ----------------------------------------------------------------------
  38. // ---------------------------------------------------------------------------
  39. // Compiler detection code (SPP_ proprocessor macros) derived from Boost
  40. // libraries. Therefore Boost software licence reproduced below.
  41. // ---------------------------------------------------------------------------
  42. // Boost Software License - Version 1.0 - August 17th, 2003
  43. //
  44. // Permission is hereby granted, free of charge, to any person or organization
  45. // obtaining a copy of the software and accompanying documentation covered by
  46. // this license (the "Software") to use, reproduce, display, distribute,
  47. // execute, and transmit the Software, and to prepare derivative works of the
  48. // Software, and to permit third-parties to whom the Software is furnished to
  49. // do so, all subject to the following:
  50. //
  51. // The copyright notices in the Software and this entire statement, including
  52. // the above license grant, this restriction and the following disclaimer,
  53. // must be included in all copies of the Software, in whole or in part, and
  54. // all derivative works of the Software, unless such copies or derivative
  55. // works are solely in the form of machine-executable object code generated by
  56. // a source language processor.
  57. //
  58. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  59. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  60. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  61. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  62. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  63. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  64. // DEALINGS IN THE SOFTWARE.
  65. // ---------------------------------------------------------------------------
  66. // some macros for portability
  67. // ---------------------------
  68. #define spp_ spp
  69. #define SPP_NAMESPACE spp_
  70. #define SPP_START_NAMESPACE namespace spp {
  71. #define SPP_END_NAMESPACE }
  72. #define SPP_GROUP_SIZE 32 // must be 32 or 64
  73. #define SPP_ALLOC_SZ 0 // must be power of 2 (0 = agressive alloc, 1 = smallest memory usage, 2 = good compromise)
  74. #define SPP_STORE_NUM_ITEMS 1 // little bit more memory, but faster!!
  75. #if (SPP_GROUP_SIZE == 32)
  76. #define SPP_SHIFT_ 5
  77. #define SPP_MASK_ 0x1F
  78. #elif (SPP_GROUP_SIZE == 64)
  79. #define SPP_SHIFT_ 6
  80. #define SPP_MASK_ 0x3F
  81. #else
  82. #error "SPP_GROUP_SIZE must be either 32 or 64"
  83. #endif
  84. // Boost like configuration
  85. // ------------------------
  86. #if defined __clang__
  87. #if defined(i386)
  88. #include <cpuid.h>
  89. inline void spp_cpuid(int info[4], int InfoType) {
  90. __cpuid_count(InfoType, 0, info[0], info[1], info[2], info[3]);
  91. }
  92. #endif
  93. #define SPP_POPCNT __builtin_popcount
  94. #define SPP_POPCNT64 __builtin_popcountll
  95. #define SPP_HAS_CSTDINT
  96. #ifndef __has_extension
  97. #define __has_extension __has_feature
  98. #endif
  99. #if !__has_feature(cxx_exceptions) && !defined(SPP_NO_EXCEPTIONS)
  100. #define SPP_NO_EXCEPTIONS
  101. #endif
  102. #if !__has_feature(cxx_rtti) && !defined(SPP_NO_RTTI)
  103. #define SPP_NO_RTTI
  104. #endif
  105. #if !__has_feature(cxx_rtti) && !defined(SPP_NO_TYPEID)
  106. #define SPP_NO_TYPEID
  107. #endif
  108. #if defined(__int64) && !defined(__GNUC__)
  109. #define SPP_HAS_MS_INT64
  110. #endif
  111. #define SPP_HAS_NRVO
  112. // Branch prediction hints
  113. #if defined(__has_builtin)
  114. #if __has_builtin(__builtin_expect)
  115. #define SPP_LIKELY(x) __builtin_expect(x, 1)
  116. #define SPP_UNLIKELY(x) __builtin_expect(x, 0)
  117. #endif
  118. #endif
  119. // Clang supports "long long" in all compilation modes.
  120. #define SPP_HAS_LONG_LONG
  121. #if !__has_feature(cxx_constexpr)
  122. #define SPP_NO_CXX11_CONSTEXPR
  123. #endif
  124. #if !__has_feature(cxx_decltype)
  125. #define SPP_NO_CXX11_DECLTYPE
  126. #endif
  127. #if !__has_feature(cxx_decltype_incomplete_return_types)
  128. #define SPP_NO_CXX11_DECLTYPE_N3276
  129. #endif
  130. #if !__has_feature(cxx_defaulted_functions)
  131. #define SPP_NO_CXX11_DEFAULTED_FUNCTIONS
  132. #endif
  133. #if !__has_feature(cxx_deleted_functions)
  134. #define SPP_NO_CXX11_DELETED_FUNCTIONS
  135. #endif
  136. #if !__has_feature(cxx_explicit_conversions)
  137. #define SPP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  138. #endif
  139. #if !__has_feature(cxx_default_function_template_args)
  140. #define SPP_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
  141. #endif
  142. #if !__has_feature(cxx_generalized_initializers)
  143. #define SPP_NO_CXX11_HDR_INITIALIZER_LIST
  144. #endif
  145. #if !__has_feature(cxx_lambdas)
  146. #define SPP_NO_CXX11_LAMBDAS
  147. #endif
  148. #if !__has_feature(cxx_local_type_template_args)
  149. #define SPP_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
  150. #endif
  151. #if !__has_feature(cxx_nullptr)
  152. #define SPP_NO_CXX11_NULLPTR
  153. #endif
  154. #if !__has_feature(cxx_range_for)
  155. #define SPP_NO_CXX11_RANGE_BASED_FOR
  156. #endif
  157. #if !__has_feature(cxx_raw_string_literals)
  158. #define SPP_NO_CXX11_RAW_LITERALS
  159. #endif
  160. #if !__has_feature(cxx_reference_qualified_functions)
  161. #define SPP_NO_CXX11_REF_QUALIFIERS
  162. #endif
  163. #if !__has_feature(cxx_generalized_initializers)
  164. #define SPP_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
  165. #endif
  166. #if !__has_feature(cxx_rvalue_references)
  167. #define SPP_NO_CXX11_RVALUE_REFERENCES
  168. #endif
  169. #if !__has_feature(cxx_strong_enums)
  170. #define SPP_NO_CXX11_SCOPED_ENUMS
  171. #endif
  172. #if !__has_feature(cxx_static_assert)
  173. #define SPP_NO_CXX11_STATIC_ASSERT
  174. #endif
  175. #if !__has_feature(cxx_alias_templates)
  176. #define SPP_NO_CXX11_TEMPLATE_ALIASES
  177. #endif
  178. #if !__has_feature(cxx_unicode_literals)
  179. #define SPP_NO_CXX11_UNICODE_LITERALS
  180. #endif
  181. #if !__has_feature(cxx_variadic_templates)
  182. #define SPP_NO_CXX11_VARIADIC_TEMPLATES
  183. #endif
  184. #if !__has_feature(cxx_user_literals)
  185. #define SPP_NO_CXX11_USER_DEFINED_LITERALS
  186. #endif
  187. #if !__has_feature(cxx_alignas)
  188. #define SPP_NO_CXX11_ALIGNAS
  189. #endif
  190. #if !__has_feature(cxx_trailing_return)
  191. #define SPP_NO_CXX11_TRAILING_RESULT_TYPES
  192. #endif
  193. #if !__has_feature(cxx_inline_namespaces)
  194. #define SPP_NO_CXX11_INLINE_NAMESPACES
  195. #endif
  196. #if !__has_feature(cxx_override_control)
  197. #define SPP_NO_CXX11_FINAL
  198. #endif
  199. #if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__))
  200. #define SPP_NO_CXX14_BINARY_LITERALS
  201. #endif
  202. #if !__has_feature(__cxx_decltype_auto__)
  203. #define SPP_NO_CXX14_DECLTYPE_AUTO
  204. #endif
  205. #if !__has_feature(__cxx_aggregate_nsdmi__)
  206. #define SPP_NO_CXX14_AGGREGATE_NSDMI
  207. #endif
  208. #if !__has_feature(__cxx_init_captures__)
  209. #define SPP_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
  210. #endif
  211. #if !__has_feature(__cxx_generic_lambdas__)
  212. #define SPP_NO_CXX14_GENERIC_LAMBDAS
  213. #endif
  214. #if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__)
  215. #define SPP_NO_CXX14_CONSTEXPR
  216. #endif
  217. #if !__has_feature(__cxx_return_type_deduction__)
  218. #define SPP_NO_CXX14_RETURN_TYPE_DEDUCTION
  219. #endif
  220. #if !__has_feature(__cxx_variable_templates__)
  221. #define SPP_NO_CXX14_VARIABLE_TEMPLATES
  222. #endif
  223. #if __cplusplus < 201400
  224. #define SPP_NO_CXX14_DIGIT_SEPARATORS
  225. #endif
  226. #if defined(__has_builtin) && __has_builtin(__builtin_unreachable)
  227. #define SPP_UNREACHABLE_RETURN(x) __builtin_unreachable();
  228. #endif
  229. #define SPP_ATTRIBUTE_UNUSED __attribute__((__unused__))
  230. #ifndef SPP_COMPILER
  231. #define SPP_COMPILER "Clang version " __clang_version__
  232. #endif
  233. #define SPP_CLANG 1
  234. #elif defined __GNUC__
  235. #define SPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
  236. // definition to expand macro then apply to pragma message
  237. // #define VALUE_TO_STRING(x) #x
  238. // #define VALUE(x) VALUE_TO_STRING(x)
  239. // #define VAR_NAME_VALUE(var) #var "=" VALUE(var)
  240. // #pragma message(VAR_NAME_VALUE(SPP_GCC_VERSION))
  241. #if defined(i386)
  242. #include <cpuid.h>
  243. inline void spp_cpuid(int info[4], int InfoType) {
  244. __cpuid_count(InfoType, 0, info[0], info[1], info[2], info[3]);
  245. }
  246. #endif
  247. // __POPCNT__ defined when the compiled with popcount support
  248. // (-mpopcnt compiler option is given for example)
  249. #ifdef __POPCNT__
  250. // slower unless compiled iwith -mpopcnt
  251. #define SPP_POPCNT __builtin_popcount
  252. #define SPP_POPCNT64 __builtin_popcountll
  253. #endif
  254. #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
  255. #define SPP_GCC_CXX11
  256. #endif
  257. #if __GNUC__ == 3
  258. #if defined (__PATHSCALE__)
  259. #define SPP_NO_TWO_PHASE_NAME_LOOKUP
  260. #define SPP_NO_IS_ABSTRACT
  261. #endif
  262. #if __GNUC_MINOR__ < 4
  263. #define SPP_NO_IS_ABSTRACT
  264. #endif
  265. #define SPP_NO_CXX11_EXTERN_TEMPLATE
  266. #endif
  267. #if __GNUC__ < 4
  268. //
  269. // All problems to gcc-3.x and earlier here:
  270. //
  271. #define SPP_NO_TWO_PHASE_NAME_LOOKUP
  272. #ifdef __OPEN64__
  273. #define SPP_NO_IS_ABSTRACT
  274. #endif
  275. #endif
  276. // GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links
  277. #if SPP_GCC_VERSION >= 30400
  278. #define SPP_HAS_PRAGMA_ONCE
  279. #endif
  280. #if SPP_GCC_VERSION < 40400
  281. // Previous versions of GCC did not completely implement value-initialization:
  282. // GCC Bug 30111, "Value-initialization of POD base class doesn't initialize
  283. // members", reported by Jonathan Wakely in 2006,
  284. // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4)
  285. // GCC Bug 33916, "Default constructor fails to initialize array members",
  286. // reported by Michael Elizabeth Chastain in 2007,
  287. // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4)
  288. // See also: http://www.boost.org/libs/utility/value_init.htm #compiler_issues
  289. #define SPP_NO_COMPLETE_VALUE_INITIALIZATION
  290. #endif
  291. #if !defined(__EXCEPTIONS) && !defined(SPP_NO_EXCEPTIONS)
  292. #define SPP_NO_EXCEPTIONS
  293. #endif
  294. //
  295. // Threading support: Turn this on unconditionally here (except for
  296. // those platforms where we can know for sure). It will get turned off again
  297. // later if no threading API is detected.
  298. //
  299. #if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__)
  300. #define SPP_HAS_THREADS
  301. #endif
  302. //
  303. // gcc has "long long"
  304. // Except on Darwin with standard compliance enabled (-pedantic)
  305. // Apple gcc helpfully defines this macro we can query
  306. //
  307. #if !defined(__DARWIN_NO_LONG_LONG)
  308. #define SPP_HAS_LONG_LONG
  309. #endif
  310. //
  311. // gcc implements the named return value optimization since version 3.1
  312. //
  313. #define SPP_HAS_NRVO
  314. // Branch prediction hints
  315. #define SPP_LIKELY(x) __builtin_expect(x, 1)
  316. #define SPP_UNLIKELY(x) __builtin_expect(x, 0)
  317. //
  318. // Dynamic shared object (DSO) and dynamic-link library (DLL) support
  319. //
  320. #if __GNUC__ >= 4
  321. #if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__)
  322. // All Win32 development environments, including 64-bit Windows and MinGW, define
  323. // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment,
  324. // so does not define _WIN32 or its variants.
  325. #define SPP_HAS_DECLSPEC
  326. #define SPP_SYMBOL_EXPORT __attribute__((__dllexport__))
  327. #define SPP_SYMBOL_IMPORT __attribute__((__dllimport__))
  328. #else
  329. #define SPP_SYMBOL_EXPORT __attribute__((__visibility__("default")))
  330. #define SPP_SYMBOL_IMPORT
  331. #endif
  332. #define SPP_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
  333. #else
  334. // config/platform/win32.hpp will define SPP_SYMBOL_EXPORT, etc., unless already defined
  335. #define SPP_SYMBOL_EXPORT
  336. #endif
  337. //
  338. // RTTI and typeinfo detection is possible post gcc-4.3:
  339. //
  340. #if SPP_GCC_VERSION > 40300
  341. #ifndef __GXX_RTTI
  342. #ifndef SPP_NO_TYPEID
  343. #define SPP_NO_TYPEID
  344. #endif
  345. #ifndef SPP_NO_RTTI
  346. #define SPP_NO_RTTI
  347. #endif
  348. #endif
  349. #endif
  350. //
  351. // Recent GCC versions have __int128 when in 64-bit mode.
  352. //
  353. // We disable this if the compiler is really nvcc with C++03 as it
  354. // doesn't actually support __int128 as of CUDA_VERSION=7500
  355. // even though it defines __SIZEOF_INT128__.
  356. // See https://svn.boost.org/trac/boost/ticket/8048
  357. // https://svn.boost.org/trac/boost/ticket/11852
  358. // Only re-enable this for nvcc if you're absolutely sure
  359. // of the circumstances under which it's supported:
  360. //
  361. #if defined(__CUDACC__)
  362. #if defined(SPP_GCC_CXX11)
  363. #define SPP_NVCC_CXX11
  364. #else
  365. #define SPP_NVCC_CXX03
  366. #endif
  367. #endif
  368. #if defined(__SIZEOF_INT128__) && !defined(SPP_NVCC_CXX03)
  369. #define SPP_HAS_INT128
  370. #endif
  371. //
  372. // Recent GCC versions have a __float128 native type, we need to
  373. // include a std lib header to detect this - not ideal, but we'll
  374. // be including <cstddef> later anyway when we select the std lib.
  375. //
  376. // Nevertheless, as of CUDA 7.5, using __float128 with the host
  377. // compiler in pre-C++11 mode is still not supported.
  378. // See https://svn.boost.org/trac/boost/ticket/11852
  379. //
  380. #ifdef __cplusplus
  381. #include <cstddef>
  382. #else
  383. #include <stddef.h>
  384. #endif
  385. #if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(SPP_NVCC_CXX03)
  386. #define SPP_HAS_FLOAT128
  387. #endif
  388. // C++0x features in 4.3.n and later
  389. //
  390. #if (SPP_GCC_VERSION >= 40300) && defined(SPP_GCC_CXX11)
  391. // C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
  392. // passed on the command line, which in turn defines
  393. // __GXX_EXPERIMENTAL_CXX0X__.
  394. #define SPP_HAS_DECLTYPE
  395. #define SPP_HAS_RVALUE_REFS
  396. #define SPP_HAS_STATIC_ASSERT
  397. #define SPP_HAS_VARIADIC_TMPL
  398. #define SPP_HAS_CSTDINT
  399. #else
  400. #define SPP_NO_CXX11_DECLTYPE
  401. #define SPP_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
  402. #define SPP_NO_CXX11_RVALUE_REFERENCES
  403. #define SPP_NO_CXX11_STATIC_ASSERT
  404. #endif
  405. // C++0x features in 4.4.n and later
  406. //
  407. #if (SPP_GCC_VERSION < 40400) || !defined(SPP_GCC_CXX11)
  408. #define SPP_NO_CXX11_AUTO_DECLARATIONS
  409. #define SPP_NO_CXX11_AUTO_MULTIDECLARATIONS
  410. #define SPP_NO_CXX11_CHAR16_T
  411. #define SPP_NO_CXX11_CHAR32_T
  412. #define SPP_NO_CXX11_HDR_INITIALIZER_LIST
  413. #define SPP_NO_CXX11_DEFAULTED_FUNCTIONS
  414. #define SPP_NO_CXX11_DELETED_FUNCTIONS
  415. #define SPP_NO_CXX11_TRAILING_RESULT_TYPES
  416. #define SPP_NO_CXX11_INLINE_NAMESPACES
  417. #define SPP_NO_CXX11_VARIADIC_TEMPLATES
  418. #endif
  419. #if SPP_GCC_VERSION < 40500
  420. #define SPP_NO_SFINAE_EXPR
  421. #endif
  422. // GCC 4.5 forbids declaration of defaulted functions in private or protected sections
  423. #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(SPP_GCC_CXX11)
  424. #define SPP_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS
  425. #endif
  426. // C++0x features in 4.5.0 and later
  427. //
  428. #if (SPP_GCC_VERSION < 40500) || !defined(SPP_GCC_CXX11)
  429. #define SPP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  430. #define SPP_NO_CXX11_LAMBDAS
  431. #define SPP_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
  432. #define SPP_NO_CXX11_RAW_LITERALS
  433. #define SPP_NO_CXX11_UNICODE_LITERALS
  434. #endif
  435. // C++0x features in 4.5.1 and later
  436. //
  437. #if (SPP_GCC_VERSION < 40501) || !defined(SPP_GCC_CXX11)
  438. // scoped enums have a serious bug in 4.4.0, so define SPP_NO_CXX11_SCOPED_ENUMS before 4.5.1
  439. // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064
  440. #define SPP_NO_CXX11_SCOPED_ENUMS
  441. #endif
  442. // C++0x features in 4.6.n and later
  443. //
  444. #if (SPP_GCC_VERSION < 40600) || !defined(SPP_GCC_CXX11)
  445. #define SPP_NO_CXX11_CONSTEXPR
  446. #define SPP_NO_CXX11_NULLPTR
  447. #define SPP_NO_CXX11_RANGE_BASED_FOR
  448. #define SPP_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
  449. #endif
  450. // C++0x features in 4.7.n and later
  451. //
  452. #if (SPP_GCC_VERSION < 40700) || !defined(SPP_GCC_CXX11)
  453. #define SPP_NO_CXX11_FINAL
  454. #define SPP_NO_CXX11_TEMPLATE_ALIASES
  455. #define SPP_NO_CXX11_USER_DEFINED_LITERALS
  456. #define SPP_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS
  457. #endif
  458. // C++0x features in 4.8.n and later
  459. //
  460. #if (SPP_GCC_VERSION < 40800) || !defined(SPP_GCC_CXX11)
  461. #define SPP_NO_CXX11_ALIGNAS
  462. #endif
  463. // C++0x features in 4.8.1 and later
  464. //
  465. #if (SPP_GCC_VERSION < 40801) || !defined(SPP_GCC_CXX11)
  466. #define SPP_NO_CXX11_DECLTYPE_N3276
  467. #define SPP_NO_CXX11_REF_QUALIFIERS
  468. #define SPP_NO_CXX14_BINARY_LITERALS
  469. #endif
  470. // C++14 features in 4.9.0 and later
  471. //
  472. #if (SPP_GCC_VERSION < 40900) || (__cplusplus < 201300)
  473. #define SPP_NO_CXX14_RETURN_TYPE_DEDUCTION
  474. #define SPP_NO_CXX14_GENERIC_LAMBDAS
  475. #define SPP_NO_CXX14_DIGIT_SEPARATORS
  476. #define SPP_NO_CXX14_DECLTYPE_AUTO
  477. #if !((SPP_GCC_VERSION >= 40801) && (SPP_GCC_VERSION < 40900) && defined(SPP_GCC_CXX11))
  478. #define SPP_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
  479. #endif
  480. #endif
  481. // C++ 14:
  482. #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304)
  483. #define SPP_NO_CXX14_AGGREGATE_NSDMI
  484. #endif
  485. #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304)
  486. #define SPP_NO_CXX14_CONSTEXPR
  487. #endif
  488. #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304)
  489. #define SPP_NO_CXX14_VARIABLE_TEMPLATES
  490. #endif
  491. //
  492. // Unused attribute:
  493. #if __GNUC__ >= 4
  494. #define SPP_ATTRIBUTE_UNUSED __attribute__((__unused__))
  495. #endif
  496. //
  497. // __builtin_unreachable:
  498. #if SPP_GCC_VERSION >= 40800
  499. #define SPP_UNREACHABLE_RETURN(x) __builtin_unreachable();
  500. #endif
  501. #ifndef SPP_COMPILER
  502. #define SPP_COMPILER "GNU C++ version " __VERSION__
  503. #endif
  504. // ConceptGCC compiler:
  505. // http://www.generic-programming.org/software/ConceptGCC/
  506. #ifdef __GXX_CONCEPTS__
  507. #define SPP_HAS_CONCEPTS
  508. #define SPP_COMPILER "ConceptGCC version " __VERSION__
  509. #endif
  510. #elif defined _MSC_VER
  511. #include <intrin.h> // for __popcnt()
  512. #define SPP_POPCNT_CHECK // slower when defined, but we have to check!
  513. #define spp_cpuid(info, x) __cpuid(info, x)
  514. #define SPP_POPCNT __popcnt
  515. #if (SPP_GROUP_SIZE == 64 && INTPTR_MAX == INT64_MAX)
  516. #define SPP_POPCNT64 __popcnt64
  517. #endif
  518. // Attempt to suppress VC6 warnings about the length of decorated names (obsolete):
  519. #pragma warning( disable : 4503 ) // warning: decorated name length exceeded
  520. #define SPP_HAS_PRAGMA_ONCE
  521. #define SPP_HAS_CSTDINT
  522. //
  523. // versions check:
  524. // we don't support Visual C++ prior to version 7.1:
  525. #if _MSC_VER < 1310
  526. #error "Antique compiler not supported"
  527. #endif
  528. #if _MSC_FULL_VER < 180020827
  529. #define SPP_NO_FENV_H
  530. #endif
  531. #if _MSC_VER < 1400
  532. // although a conforming signature for swprint exists in VC7.1
  533. // it appears not to actually work:
  534. #define SPP_NO_SWPRINTF
  535. // Our extern template tests also fail for this compiler:
  536. #define SPP_NO_CXX11_EXTERN_TEMPLATE
  537. // Variadic macros do not exist for VC7.1 and lower
  538. #define SPP_NO_CXX11_VARIADIC_MACROS
  539. #endif
  540. #if _MSC_VER < 1500 // 140X == VC++ 8.0
  541. #undef SPP_HAS_CSTDINT
  542. #define SPP_NO_MEMBER_TEMPLATE_FRIENDS
  543. #endif
  544. #if _MSC_VER < 1600 // 150X == VC++ 9.0
  545. // A bug in VC9:
  546. #define SPP_NO_ADL_BARRIER
  547. #endif
  548. // MSVC (including the latest checked version) has not yet completely
  549. // implemented value-initialization, as is reported:
  550. // "VC++ does not value-initialize members of derived classes without
  551. // user-declared constructor", reported in 2009 by Sylvester Hesp:
  552. // https: //connect.microsoft.com/VisualStudio/feedback/details/484295
  553. // "Presence of copy constructor breaks member class initialization",
  554. // reported in 2009 by Alex Vakulenko:
  555. // https: //connect.microsoft.com/VisualStudio/feedback/details/499606
  556. // "Value-initialization in new-expression", reported in 2005 by
  557. // Pavel Kuznetsov (MetaCommunications Engineering):
  558. // https: //connect.microsoft.com/VisualStudio/feedback/details/100744
  559. // See also: http: //www.boost.org/libs/utility/value_init.htm #compiler_issues
  560. // (Niels Dekker, LKEB, May 2010)
  561. #define SPP_NO_COMPLETE_VALUE_INITIALIZATION
  562. #ifndef _NATIVE_WCHAR_T_DEFINED
  563. #define SPP_NO_INTRINSIC_WCHAR_T
  564. #endif
  565. //
  566. // check for exception handling support:
  567. #if !defined(_CPPUNWIND) && !defined(SPP_NO_EXCEPTIONS)
  568. #define SPP_NO_EXCEPTIONS
  569. #endif
  570. //
  571. // __int64 support:
  572. //
  573. #define SPP_HAS_MS_INT64
  574. #if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400)
  575. #define SPP_HAS_LONG_LONG
  576. #else
  577. #define SPP_NO_LONG_LONG
  578. #endif
  579. #if (_MSC_VER >= 1400) && !defined(_DEBUG)
  580. #define SPP_HAS_NRVO
  581. #endif
  582. #if _MSC_VER >= 1500 // 150X == VC++ 9.0
  583. #define SPP_HAS_PRAGMA_DETECT_MISMATCH
  584. #endif
  585. //
  586. // disable Win32 API's if compiler extensions are
  587. // turned off:
  588. //
  589. #if !defined(_MSC_EXTENSIONS) && !defined(SPP_DISABLE_WIN32)
  590. #define SPP_DISABLE_WIN32
  591. #endif
  592. #if !defined(_CPPRTTI) && !defined(SPP_NO_RTTI)
  593. #define SPP_NO_RTTI
  594. #endif
  595. //
  596. // TR1 features:
  597. //
  598. #if _MSC_VER >= 1700
  599. // #define SPP_HAS_TR1_HASH // don't know if this is true yet.
  600. // #define SPP_HAS_TR1_TYPE_TRAITS // don't know if this is true yet.
  601. #define SPP_HAS_TR1_UNORDERED_MAP
  602. #define SPP_HAS_TR1_UNORDERED_SET
  603. #endif
  604. //
  605. // C++0x features
  606. //
  607. // See above for SPP_NO_LONG_LONG
  608. // C++ features supported by VC++ 10 (aka 2010)
  609. //
  610. #if _MSC_VER < 1600
  611. #define SPP_NO_CXX11_AUTO_DECLARATIONS
  612. #define SPP_NO_CXX11_AUTO_MULTIDECLARATIONS
  613. #define SPP_NO_CXX11_LAMBDAS
  614. #define SPP_NO_CXX11_RVALUE_REFERENCES
  615. #define SPP_NO_CXX11_STATIC_ASSERT
  616. #define SPP_NO_CXX11_NULLPTR
  617. #define SPP_NO_CXX11_DECLTYPE
  618. #endif // _MSC_VER < 1600
  619. #if _MSC_VER >= 1600
  620. #define SPP_HAS_STDINT_H
  621. #endif
  622. // C++11 features supported by VC++ 11 (aka 2012)
  623. //
  624. #if _MSC_VER < 1700
  625. #define SPP_NO_CXX11_FINAL
  626. #define SPP_NO_CXX11_RANGE_BASED_FOR
  627. #define SPP_NO_CXX11_SCOPED_ENUMS
  628. #endif // _MSC_VER < 1700
  629. // C++11 features supported by VC++ 12 (aka 2013).
  630. //
  631. #if _MSC_FULL_VER < 180020827
  632. #define SPP_NO_CXX11_DEFAULTED_FUNCTIONS
  633. #define SPP_NO_CXX11_DELETED_FUNCTIONS
  634. #define SPP_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
  635. #define SPP_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
  636. #define SPP_NO_CXX11_RAW_LITERALS
  637. #define SPP_NO_CXX11_TEMPLATE_ALIASES
  638. #define SPP_NO_CXX11_TRAILING_RESULT_TYPES
  639. #define SPP_NO_CXX11_VARIADIC_TEMPLATES
  640. #define SPP_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
  641. #define SPP_NO_CXX11_DECLTYPE_N3276
  642. #endif
  643. // C++11 features supported by VC++ 14 (aka 2014) CTP1
  644. #if (_MSC_FULL_VER < 190021730)
  645. #define SPP_NO_CXX11_REF_QUALIFIERS
  646. #define SPP_NO_CXX11_USER_DEFINED_LITERALS
  647. #define SPP_NO_CXX11_ALIGNAS
  648. #define SPP_NO_CXX11_INLINE_NAMESPACES
  649. #define SPP_NO_CXX14_DECLTYPE_AUTO
  650. #define SPP_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
  651. #define SPP_NO_CXX14_RETURN_TYPE_DEDUCTION
  652. #define SPP_NO_CXX11_HDR_INITIALIZER_LIST
  653. #endif
  654. // C++11 features not supported by any versions
  655. #define SPP_NO_CXX11_CHAR16_T
  656. #define SPP_NO_CXX11_CHAR32_T
  657. #define SPP_NO_CXX11_CONSTEXPR
  658. #define SPP_NO_CXX11_UNICODE_LITERALS
  659. #define SPP_NO_SFINAE_EXPR
  660. #define SPP_NO_TWO_PHASE_NAME_LOOKUP
  661. // C++ 14:
  662. #if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304)
  663. #define SPP_NO_CXX14_AGGREGATE_NSDMI
  664. #endif
  665. #if !defined(__cpp_binary_literals) || (__cpp_binary_literals < 201304)
  666. #define SPP_NO_CXX14_BINARY_LITERALS
  667. #endif
  668. #if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304)
  669. #define SPP_NO_CXX14_CONSTEXPR
  670. #endif
  671. #if (__cplusplus < 201304) // There's no SD6 check for this....
  672. #define SPP_NO_CXX14_DIGIT_SEPARATORS
  673. #endif
  674. #if !defined(__cpp_generic_lambdas) || (__cpp_generic_lambdas < 201304)
  675. #define SPP_NO_CXX14_GENERIC_LAMBDAS
  676. #endif
  677. #if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304)
  678. #define SPP_NO_CXX14_VARIABLE_TEMPLATES
  679. #endif
  680. #endif
  681. // from boost/config/suffix.hpp
  682. // ----------------------------
  683. #ifndef SPP_ATTRIBUTE_UNUSED
  684. #define SPP_ATTRIBUTE_UNUSED
  685. #endif
  686. // includes
  687. // --------
  688. #if defined(SPP_HAS_CSTDINT) && (__cplusplus >= 201103)
  689. #include <cstdint>
  690. #else
  691. #if defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX)
  692. #include <inttypes.h>
  693. #else
  694. #include <stdint.h>
  695. #endif
  696. #endif
  697. #include <cassert>
  698. #include <cstring>
  699. #include <string>
  700. #include <limits> // for numeric_limits
  701. #include <algorithm> // For swap(), eg
  702. #include <iterator> // for iterator tags
  703. #include <functional> // for equal_to<>, select1st<>, std::unary_function, etc
  704. #include <memory> // for alloc, uninitialized_copy, uninitialized_fill
  705. #include <cstdlib> // for malloc/realloc/free
  706. #include <cstddef> // for ptrdiff_t
  707. #include <new> // for placement new
  708. #include <stdexcept> // For length_error
  709. #include <utility> // for pair<>
  710. #include <cstdio>
  711. #include <iosfwd>
  712. #include <ios>
  713. #if !defined(SPP_NO_CXX11_HDR_INITIALIZER_LIST)
  714. #include <initializer_list>
  715. #endif
  716. #if (SPP_GROUP_SIZE == 32)
  717. typedef uint32_t group_bm_type;
  718. #else
  719. typedef uint64_t group_bm_type;
  720. #endif
  721. template<int S, int H> class HashObject; // for Google's benchmark, not in spp namespace!
  722. // ----------------------------------------------------------------------
  723. // H A S H F U N C T I O N S
  724. // ----------------------------
  725. //
  726. // Implements spp::spp_hash() and spp::hash_combine()
  727. //
  728. // This is exactly the content of spp_utils.h, except for the copyright
  729. // attributions at the beginning
  730. //
  731. // WARNING: Any change here has to be duplicated in spp_utils.h.
  732. // ----------------------------------------------------------------------
  733. #if !defined(spp_utils_h_guard_)
  734. #define spp_utils_h_guard_
  735. #if defined(_MSC_VER)
  736. #if (_MSC_VER >= 1600 ) // vs2010 (1900 is vs2015)
  737. #include <functional>
  738. #define SPP_HASH_CLASS std::hash
  739. #else
  740. #include <hash_map>
  741. #define SPP_HASH_CLASS stdext::hash_compare
  742. #endif
  743. #if (_MSC_FULL_VER < 190021730)
  744. #define SPP_NO_CXX11_NOEXCEPT
  745. #endif
  746. #elif defined(__GNUC__)
  747. #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
  748. #include <functional>
  749. #define SPP_HASH_CLASS std::hash
  750. #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) < 40600
  751. #define SPP_NO_CXX11_NOEXCEPT
  752. #endif
  753. #else
  754. #include <tr1/unordered_map>
  755. #define SPP_HASH_CLASS std::tr1::hash
  756. #define SPP_NO_CXX11_NOEXCEPT
  757. #endif
  758. #elif defined __clang__
  759. #include <functional>
  760. #define SPP_HASH_CLASS std::hash
  761. #if !__has_feature(cxx_noexcept)
  762. #define SPP_NO_CXX11_NOEXCEPT
  763. #endif
  764. #else
  765. #include <functional>
  766. #define SPP_HASH_CLASS std::hash
  767. #endif
  768. #ifdef SPP_NO_CXX11_NOEXCEPT
  769. #define SPP_NOEXCEPT
  770. #else
  771. #define SPP_NOEXCEPT noexcept
  772. #endif
  773. #ifdef SPP_NO_CXX11_CONSTEXPR
  774. #define SPP_CONSTEXPR
  775. #else
  776. #define SPP_CONSTEXPR constexpr
  777. #endif
  778. #define SPP_INLINE
  779. #ifndef SPP_NAMESPACE
  780. #define SPP_NAMESPACE spp
  781. #endif
  782. namespace SPP_NAMESPACE
  783. {
  784. template <class T>
  785. struct spp_hash
  786. {
  787. SPP_INLINE size_t operator()(const T &__v) const SPP_NOEXCEPT
  788. {
  789. SPP_HASH_CLASS<T> hasher;
  790. return hasher(__v);
  791. }
  792. };
  793. template <class T>
  794. struct spp_hash<T *>
  795. {
  796. static size_t spp_log2 (size_t val) SPP_NOEXCEPT
  797. {
  798. size_t res = 0;
  799. while (val > 1)
  800. {
  801. val >>= 1;
  802. res++;
  803. }
  804. return res;
  805. }
  806. SPP_INLINE size_t operator()(const T *__v) const SPP_NOEXCEPT
  807. {
  808. static const size_t shift = 3; // spp_log2(1 + sizeof(T)); // T might be incomplete!
  809. return static_cast<size_t>((*(reinterpret_cast<const uintptr_t *>(&__v))) >> shift);
  810. }
  811. };
  812. // from http://burtleburtle.net/bob/hash/integer.html
  813. // fast and efficient for power of two table sizes where we always
  814. // consider the last bits.
  815. // ---------------------------------------------------------------
  816. inline size_t spp_mix_32(uint32_t a)
  817. {
  818. a = a ^ (a >> 4);
  819. a = (a ^ 0xdeadbeef) + (a << 5);
  820. a = a ^ (a >> 11);
  821. return static_cast<size_t>(a);
  822. }
  823. // Maybe we should do a more thorough scrambling as described in
  824. // https://gist.github.com/badboy/6267743
  825. // -------------------------------------------------------------
  826. inline size_t spp_mix_64(uint64_t a)
  827. {
  828. a = a ^ (a >> 4);
  829. a = (a ^ 0xdeadbeef) + (a << 5);
  830. a = a ^ (a >> 11);
  831. return a;
  832. }
  833. template <>
  834. struct spp_hash<bool> : public std::unary_function<bool, size_t>
  835. {
  836. SPP_INLINE size_t operator()(bool __v) const SPP_NOEXCEPT
  837. { return static_cast<size_t>(__v); }
  838. };
  839. template <>
  840. struct spp_hash<char> : public std::unary_function<char, size_t>
  841. {
  842. SPP_INLINE size_t operator()(char __v) const SPP_NOEXCEPT
  843. { return static_cast<size_t>(__v); }
  844. };
  845. template <>
  846. struct spp_hash<signed char> : public std::unary_function<signed char, size_t>
  847. {
  848. SPP_INLINE size_t operator()(signed char __v) const SPP_NOEXCEPT
  849. { return static_cast<size_t>(__v); }
  850. };
  851. template <>
  852. struct spp_hash<unsigned char> : public std::unary_function<unsigned char, size_t>
  853. {
  854. SPP_INLINE size_t operator()(unsigned char __v) const SPP_NOEXCEPT
  855. { return static_cast<size_t>(__v); }
  856. };
  857. template <>
  858. struct spp_hash<wchar_t> : public std::unary_function<wchar_t, size_t>
  859. {
  860. SPP_INLINE size_t operator()(wchar_t __v) const SPP_NOEXCEPT
  861. { return static_cast<size_t>(__v); }
  862. };
  863. template <>
  864. struct spp_hash<int16_t> : public std::unary_function<int16_t, size_t>
  865. {
  866. SPP_INLINE size_t operator()(int16_t __v) const SPP_NOEXCEPT
  867. { return spp_mix_32(static_cast<uint32_t>(__v)); }
  868. };
  869. template <>
  870. struct spp_hash<uint16_t> : public std::unary_function<uint16_t, size_t>
  871. {
  872. SPP_INLINE size_t operator()(uint16_t __v) const SPP_NOEXCEPT
  873. { return spp_mix_32(static_cast<uint32_t>(__v)); }
  874. };
  875. template <>
  876. struct spp_hash<int32_t> : public std::unary_function<int32_t, size_t>
  877. {
  878. SPP_INLINE size_t operator()(int32_t __v) const SPP_NOEXCEPT
  879. { return spp_mix_32(static_cast<uint32_t>(__v)); }
  880. };
  881. template <>
  882. struct spp_hash<uint32_t> : public std::unary_function<uint32_t, size_t>
  883. {
  884. SPP_INLINE size_t operator()(uint32_t __v) const SPP_NOEXCEPT
  885. { return spp_mix_32(static_cast<uint32_t>(__v)); }
  886. };
  887. template <>
  888. struct spp_hash<int64_t> : public std::unary_function<int64_t, size_t>
  889. {
  890. SPP_INLINE size_t operator()(int64_t __v) const SPP_NOEXCEPT
  891. { return spp_mix_64(static_cast<uint64_t>(__v)); }
  892. };
  893. template <>
  894. struct spp_hash<uint64_t> : public std::unary_function<uint64_t, size_t>
  895. {
  896. SPP_INLINE size_t operator()(uint64_t __v) const SPP_NOEXCEPT
  897. { return spp_mix_64(static_cast<uint64_t>(__v)); }
  898. };
  899. template <>
  900. struct spp_hash<float> : public std::unary_function<float, size_t>
  901. {
  902. SPP_INLINE size_t operator()(float __v) const SPP_NOEXCEPT
  903. {
  904. // -0.0 and 0.0 should return same hash
  905. uint32_t *as_int = reinterpret_cast<uint32_t *>(&__v);
  906. return (__v == 0) ? static_cast<size_t>(0) : spp_mix_32(*as_int);
  907. }
  908. };
  909. template <>
  910. struct spp_hash<double> : public std::unary_function<double, size_t>
  911. {
  912. SPP_INLINE size_t operator()(double __v) const SPP_NOEXCEPT
  913. {
  914. // -0.0 and 0.0 should return same hash
  915. uint64_t *as_int = reinterpret_cast<uint64_t *>(&__v);
  916. return (__v == 0) ? static_cast<size_t>(0) : spp_mix_64(*as_int);
  917. }
  918. };
  919. template <class T, int sz> struct Combiner
  920. {
  921. inline void operator()(T& seed, T value);
  922. };
  923. template <class T> struct Combiner<T, 4>
  924. {
  925. inline void operator()(T& seed, T value)
  926. {
  927. seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  928. }
  929. };
  930. template <class T> struct Combiner<T, 8>
  931. {
  932. inline void operator()(T& seed, T value)
  933. {
  934. seed ^= value + T(0xc6a4a7935bd1e995) + (seed << 6) + (seed >> 2);
  935. }
  936. };
  937. template <class T>
  938. inline void hash_combine(std::size_t& seed, T const& v)
  939. {
  940. spp::spp_hash<T> hasher;
  941. Combiner<std::size_t, sizeof(std::size_t)> combiner;
  942. combiner(seed, hasher(v));
  943. }
  944. }
  945. #endif // spp_utils_h_guard_
  946. SPP_START_NAMESPACE
  947. // ----------------------------------------------------------------------
  948. // U T I L F U N C T I O N S
  949. // ----------------------------------------------------------------------
  950. template <class E>
  951. inline void throw_exception(const E& exception)
  952. {
  953. #if !defined(SPP_NO_EXCEPTIONS)
  954. throw exception;
  955. #else
  956. assert(0);
  957. abort();
  958. #endif
  959. }
  960. // ----------------------------------------------------------------------
  961. // M U T A B L E P A I R H A C K
  962. // turn mutable std::pair<K, V> into correct value_type std::pair<const K, V>
  963. // ----------------------------------------------------------------------
  964. template <class T>
  965. struct cvt
  966. {
  967. typedef T type;
  968. };
  969. template <class K, class V>
  970. struct cvt<std::pair<K, V> >
  971. {
  972. typedef std::pair<const K, V> type;
  973. };
  974. template <class K, class V>
  975. struct cvt<const std::pair<K, V> >
  976. {
  977. typedef const std::pair<const K, V> type;
  978. };
  979. // ----------------------------------------------------------------------
  980. // M O V E I T E R A T O R
  981. // ----------------------------------------------------------------------
  982. #ifdef SPP_NO_CXX11_RVALUE_REFERENCES
  983. #define MK_MOVE_IT(p) (p)
  984. #else
  985. #define MK_MOVE_IT(p) std::make_move_iterator(p)
  986. #endif
  987. // ----------------------------------------------------------------------
  988. // A L L O C A T O R S T U F F
  989. // ----------------------------------------------------------------------
  990. template<class T>
  991. class libc_allocator_with_realloc
  992. {
  993. public:
  994. typedef T value_type;
  995. typedef size_t size_type;
  996. typedef ptrdiff_t difference_type;
  997. typedef T* pointer;
  998. typedef const T* const_pointer;
  999. typedef T& reference;
  1000. typedef const T& const_reference;
  1001. libc_allocator_with_realloc() {}
  1002. libc_allocator_with_realloc(const libc_allocator_with_realloc& /*unused*/) {}
  1003. ~libc_allocator_with_realloc() {}
  1004. pointer address(reference r) const { return &r; }
  1005. const_pointer address(const_reference r) const { return &r; }
  1006. pointer allocate(size_type n, const_pointer /*unused*/= 0)
  1007. {
  1008. return static_cast<pointer>(malloc(n * sizeof(value_type)));
  1009. }
  1010. void deallocate(pointer p, size_type /*unused*/)
  1011. {
  1012. free(p);
  1013. }
  1014. pointer reallocate(pointer p, size_type n)
  1015. {
  1016. return static_cast<pointer>(realloc(p, n * sizeof(value_type)));
  1017. }
  1018. size_type max_size() const
  1019. {
  1020. return static_cast<size_type>(-1) / sizeof(value_type);
  1021. }
  1022. void construct(pointer p, const value_type& val)
  1023. {
  1024. new(p) value_type(val);
  1025. }
  1026. void destroy(pointer p) { p->~value_type(); }
  1027. template <class U>
  1028. explicit libc_allocator_with_realloc(const libc_allocator_with_realloc<U>& /*unused*/) {}
  1029. template<class U>
  1030. struct rebind
  1031. {
  1032. typedef libc_allocator_with_realloc<U> other;
  1033. };
  1034. };
  1035. // ----------------------------------------------------------------------
  1036. // libc_allocator_with_realloc<void> specialization.
  1037. // ----------------------------------------------------------------------
  1038. template<>
  1039. class libc_allocator_with_realloc<void>
  1040. {
  1041. public:
  1042. typedef void value_type;
  1043. typedef size_t size_type;
  1044. typedef ptrdiff_t difference_type;
  1045. typedef void* pointer;
  1046. typedef const void* const_pointer;
  1047. template<class U>
  1048. struct rebind
  1049. {
  1050. typedef libc_allocator_with_realloc<U> other;
  1051. };
  1052. };
  1053. template<class T>
  1054. inline bool operator==(const libc_allocator_with_realloc<T>& /*unused*/,
  1055. const libc_allocator_with_realloc<T>& /*unused*/)
  1056. {
  1057. return true;
  1058. }
  1059. template<class T>
  1060. inline bool operator!=(const libc_allocator_with_realloc<T>& /*unused*/,
  1061. const libc_allocator_with_realloc<T>& /*unused*/)
  1062. {
  1063. return false;
  1064. }
  1065. // ----------------------------------------------------------------------
  1066. // I N T E R N A L S T U F F
  1067. // ----------------------------------------------------------------------
  1068. #ifdef SPP_NO_CXX11_STATIC_ASSERT
  1069. template <bool> struct SppCompileAssert { };
  1070. #define SPP_COMPILE_ASSERT(expr, msg) \
  1071. SPP_ATTRIBUTE_UNUSED typedef SppCompileAssert<(bool(expr))> spp_bogus_[bool(expr) ? 1 : -1]
  1072. #else
  1073. #define SPP_COMPILE_ASSERT static_assert
  1074. #endif
  1075. namespace sparsehash_internal
  1076. {
  1077. // Adaptor methods for reading/writing data from an INPUT or OUPTUT
  1078. // variable passed to serialize() or unserialize(). For now we
  1079. // have implemented INPUT/OUTPUT for FILE*, istream*/ostream* (note
  1080. // they are pointers, unlike typical use), or else a pointer to
  1081. // something that supports a Read()/Write() method.
  1082. //
  1083. // For technical reasons, we implement read_data/write_data in two
  1084. // stages. The actual work is done in *_data_internal, which takes
  1085. // the stream argument twice: once as a template type, and once with
  1086. // normal type information. (We only use the second version.) We do
  1087. // this because of how C++ picks what function overload to use. If we
  1088. // implemented this the naive way:
  1089. // bool read_data(istream* is, const void* data, size_t length);
  1090. // template<typename T> read_data(T* fp, const void* data, size_t length);
  1091. // C++ would prefer the second version for every stream type except
  1092. // istream. However, we want C++ to prefer the first version for
  1093. // streams that are *subclasses* of istream, such as istringstream.
  1094. // This is not possible given the way template types are resolved. So
  1095. // we split the stream argument in two, one of which is templated and
  1096. // one of which is not. The specialized functions (like the istream
  1097. // version above) ignore the template arg and use the second, 'type'
  1098. // arg, getting subclass matching as normal. The 'catch-all'
  1099. // functions (the second version above) use the template arg to deduce
  1100. // the type, and use a second, void* arg to achieve the desired
  1101. // 'catch-all' semantics.
  1102. // ----- low-level I/O for FILE* ----
  1103. template<typename Ignored>
  1104. inline bool read_data_internal(Ignored* /*unused*/, FILE* fp,
  1105. void* data, size_t length)
  1106. {
  1107. return fread(data, length, 1, fp) == 1;
  1108. }
  1109. template<typename Ignored>
  1110. inline bool write_data_internal(Ignored* /*unused*/, FILE* fp,
  1111. const void* data, size_t length)
  1112. {
  1113. return fwrite(data, length, 1, fp) == 1;
  1114. }
  1115. // ----- low-level I/O for iostream ----
  1116. // We want the caller to be responsible for #including <iostream>, not
  1117. // us, because iostream is a big header! According to the standard,
  1118. // it's only legal to delay the instantiation the way we want to if
  1119. // the istream/ostream is a template type. So we jump through hoops.
  1120. template<typename ISTREAM>
  1121. inline bool read_data_internal_for_istream(ISTREAM* fp,
  1122. void* data, size_t length)
  1123. {
  1124. return fp->read(reinterpret_cast<char*>(data),
  1125. static_cast<std::streamsize>(length)).good();
  1126. }
  1127. template<typename Ignored>
  1128. inline bool read_data_internal(Ignored* /*unused*/, std::istream* fp,
  1129. void* data, size_t length)
  1130. {
  1131. return read_data_internal_for_istream(fp, data, length);
  1132. }
  1133. template<typename OSTREAM>
  1134. inline bool write_data_internal_for_ostream(OSTREAM* fp,
  1135. const void* data, size_t length)
  1136. {
  1137. return fp->write(reinterpret_cast<const char*>(data),
  1138. static_cast<std::streamsize>(length)).good();
  1139. }
  1140. template<typename Ignored>
  1141. inline bool write_data_internal(Ignored* /*unused*/, std::ostream* fp,
  1142. const void* data, size_t length)
  1143. {
  1144. return write_data_internal_for_ostream(fp, data, length);
  1145. }
  1146. // ----- low-level I/O for custom streams ----
  1147. // The INPUT type needs to support a Read() method that takes a
  1148. // buffer and a length and returns the number of bytes read.
  1149. template <typename INPUT>
  1150. inline bool read_data_internal(INPUT* fp, void* /*unused*/,
  1151. void* data, size_t length)
  1152. {
  1153. return static_cast<size_t>(fp->Read(data, length)) == length;
  1154. }
  1155. // The OUTPUT type needs to support a Write() operation that takes
  1156. // a buffer and a length and returns the number of bytes written.
  1157. template <typename OUTPUT>
  1158. inline bool write_data_internal(OUTPUT* fp, void* /*unused*/,
  1159. const void* data, size_t length)
  1160. {
  1161. return static_cast<size_t>(fp->Write(data, length)) == length;
  1162. }
  1163. // ----- low-level I/O: the public API ----
  1164. template <typename INPUT>
  1165. inline bool read_data(INPUT* fp, void* data, size_t length)
  1166. {
  1167. return read_data_internal(fp, fp, data, length);
  1168. }
  1169. template <typename OUTPUT>
  1170. inline bool write_data(OUTPUT* fp, const void* data, size_t length)
  1171. {
  1172. return write_data_internal(fp, fp, data, length);
  1173. }
  1174. // Uses read_data() and write_data() to read/write an integer.
  1175. // length is the number of bytes to read/write (which may differ
  1176. // from sizeof(IntType), allowing us to save on a 32-bit system
  1177. // and load on a 64-bit system). Excess bytes are taken to be 0.
  1178. // INPUT and OUTPUT must match legal inputs to read/write_data (above).
  1179. // --------------------------------------------------------------------
  1180. template <typename INPUT, typename IntType>
  1181. bool read_bigendian_number(INPUT* fp, IntType* value, size_t length)
  1182. {
  1183. *value = 0;
  1184. unsigned char byte;
  1185. // We require IntType to be unsigned or else the shifting gets all screwy.
  1186. SPP_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0), "serializing_int_requires_an_unsigned_type");
  1187. for (size_t i = 0; i < length; ++i)
  1188. {
  1189. if (!read_data(fp, &byte, sizeof(byte)))
  1190. return false;
  1191. *value |= static_cast<IntType>(byte) << ((length - 1 - i) * 8);
  1192. }
  1193. return true;
  1194. }
  1195. template <typename OUTPUT, typename IntType>
  1196. bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length)
  1197. {
  1198. unsigned char byte;
  1199. // We require IntType to be unsigned or else the shifting gets all screwy.
  1200. SPP_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0), "serializing_int_requires_an_unsigned_type");
  1201. for (size_t i = 0; i < length; ++i)
  1202. {
  1203. byte = (sizeof(value) <= length-1 - i)
  1204. ? static_cast<unsigned char>(0) : static_cast<unsigned char>((value >> ((length-1 - i) * 8)) & 255);
  1205. if (!write_data(fp, &byte, sizeof(byte))) return false;
  1206. }
  1207. return true;
  1208. }
  1209. // If your keys and values are simple enough, you can pass this
  1210. // serializer to serialize()/unserialize(). "Simple enough" means
  1211. // value_type is a POD type that contains no pointers. Note,
  1212. // however, we don't try to normalize endianness.
  1213. // This is the type used for NopointerSerializer.
  1214. // ---------------------------------------------------------------
  1215. template <typename value_type> struct pod_serializer
  1216. {
  1217. template <typename INPUT>
  1218. bool operator()(INPUT* fp, value_type* value) const
  1219. {
  1220. return read_data(fp, value, sizeof(*value));
  1221. }
  1222. template <typename OUTPUT>
  1223. bool operator()(OUTPUT* fp, const value_type& value) const
  1224. {
  1225. return write_data(fp, &value, sizeof(value));
  1226. }
  1227. };
  1228. // Settings contains parameters for growing and shrinking the table.
  1229. // It also packages zero-size functor (ie. hasher).
  1230. //
  1231. // It does some munging of the hash value for the cases where
  1232. // the original hash function is not be very good.
  1233. // ---------------------------------------------------------------
  1234. template<typename Key, typename HashFunc, typename SizeType, int HT_MIN_BUCKETS>
  1235. class sh_hashtable_settings : public HashFunc
  1236. {
  1237. private:
  1238. #ifndef SPP_MIX_HASH
  1239. template <class T, int sz> struct Mixer
  1240. {
  1241. inline T operator()(T h) const { return h; }
  1242. };
  1243. #else
  1244. template <class T, int sz> struct Mixer
  1245. {
  1246. inline T operator()(T h) const;
  1247. };
  1248. template <class T> struct Mixer<T, 4>
  1249. {
  1250. inline T operator()(T h) const
  1251. {
  1252. // from Thomas Wang - https://gist.github.com/badboy/6267743
  1253. // ---------------------------------------------------------
  1254. h = (h ^ 61) ^ (h >> 16);
  1255. h = h + (h << 3);
  1256. h = h ^ (h >> 4);
  1257. h = h * 0x27d4eb2d;
  1258. h = h ^ (h >> 15);
  1259. return h;
  1260. }
  1261. };
  1262. template <class T> struct Mixer<T, 8>
  1263. {
  1264. inline T operator()(T h) const
  1265. {
  1266. // from Thomas Wang - https://gist.github.com/badboy/6267743
  1267. // ---------------------------------------------------------
  1268. h = (~h) + (h << 21); // h = (h << 21) - h - 1;
  1269. h = h ^ (h >> 24);
  1270. h = (h + (h << 3)) + (h << 8); // h * 265
  1271. h = h ^ (h >> 14);
  1272. h = (h + (h << 2)) + (h << 4); // h * 21
  1273. h = h ^ (h >> 28);
  1274. h = h + (h << 31);
  1275. return h;
  1276. }
  1277. };
  1278. #endif
  1279. public:
  1280. typedef Key key_type;
  1281. typedef HashFunc hasher;
  1282. typedef SizeType size_type;
  1283. public:
  1284. sh_hashtable_settings(const hasher& hf,
  1285. const float ht_occupancy_flt,
  1286. const float ht_empty_flt)
  1287. : hasher(hf),
  1288. enlarge_threshold_(0),
  1289. shrink_threshold_(0),
  1290. consider_shrink_(false),
  1291. num_ht_copies_(0)
  1292. {
  1293. set_enlarge_factor(ht_occupancy_flt);
  1294. set_shrink_factor(ht_empty_flt);
  1295. }
  1296. size_t hash(const key_type& v) const
  1297. {
  1298. size_t h = hasher::operator()(v);
  1299. Mixer<size_t, sizeof(size_t)> mixer;
  1300. return mixer(h);
  1301. }
  1302. float enlarge_factor() const { return enlarge_factor_; }
  1303. void set_enlarge_factor(float f) { enlarge_factor_ = f; }
  1304. float shrink_factor() const { return shrink_factor_; }
  1305. void set_shrink_factor(float f) { shrink_factor_ = f; }
  1306. size_type enlarge_threshold() const { return enlarge_threshold_; }
  1307. void set_enlarge_threshold(size_type t) { enlarge_threshold_ = t; }
  1308. size_type shrink_threshold() const { return shrink_threshold_; }
  1309. void set_shrink_threshold(size_type t) { shrink_threshold_ = t; }
  1310. size_type enlarge_size(size_type x) const { return static_cast<size_type>(x * enlarge_factor_); }
  1311. size_type shrink_size(size_type x) const { return static_cast<size_type>(x * shrink_factor_); }
  1312. bool consider_shrink() const { return consider_shrink_; }
  1313. void set_consider_shrink(bool t) { consider_shrink_ = t; }
  1314. unsigned int num_ht_copies() const { return num_ht_copies_; }
  1315. void inc_num_ht_copies() { ++num_ht_copies_; }
  1316. // Reset the enlarge and shrink thresholds
  1317. void reset_thresholds(size_type num_buckets)
  1318. {
  1319. set_enlarge_threshold(enlarge_size(num_buckets));
  1320. set_shrink_threshold(shrink_size(num_buckets));
  1321. // whatever caused us to reset already considered
  1322. set_consider_shrink(false);
  1323. }
  1324. // Caller is resposible for calling reset_threshold right after
  1325. // set_resizing_parameters.
  1326. // ------------------------------------------------------------
  1327. void set_resizing_parameters(float shrink, float grow)
  1328. {
  1329. assert(shrink >= 0.0f);
  1330. assert(grow <= 1.0f);
  1331. if (shrink > grow/2.0f)
  1332. shrink = grow / 2.0f; // otherwise we thrash hashtable size
  1333. set_shrink_factor(shrink);
  1334. set_enlarge_factor(grow);
  1335. }
  1336. // This is the smallest size a hashtable can be without being too crowded
  1337. // If you like, you can give a min #buckets as well as a min #elts
  1338. // ----------------------------------------------------------------------
  1339. size_type min_buckets(size_type num_elts, size_type min_buckets_wanted)
  1340. {
  1341. float enlarge = enlarge_factor();
  1342. size_type sz = HT_MIN_BUCKETS; // min buckets allowed
  1343. while (sz < min_buckets_wanted ||
  1344. num_elts >= static_cast<size_type>(sz * enlarge))
  1345. {
  1346. // This just prevents overflowing size_type, since sz can exceed
  1347. // max_size() here.
  1348. // -------------------------------------------------------------
  1349. if (static_cast<size_type>(sz * 2) < sz)
  1350. throw_exception(std::length_error("resize overflow")); // protect against overflow
  1351. sz *= 2;
  1352. }
  1353. return sz;
  1354. }
  1355. private:
  1356. size_type enlarge_threshold_; // table.size() * enlarge_factor
  1357. size_type shrink_threshold_; // table.size() * shrink_factor
  1358. float enlarge_factor_; // how full before resize
  1359. float shrink_factor_; // how empty before resize
  1360. bool consider_shrink_; // if we should try to shrink before next insert
  1361. unsigned int num_ht_copies_; // num_ht_copies is a counter incremented every Copy/Move
  1362. };
  1363. } // namespace sparsehash_internal
  1364. #undef SPP_COMPILE_ASSERT
  1365. // ----------------------------------------------------------------------
  1366. // S P A R S E T A B L E
  1367. // ----------------------------------------------------------------------
  1368. //
  1369. // A sparsetable is a random container that implements a sparse array,
  1370. // that is, an array that uses very little memory to store unassigned
  1371. // indices (in this case, between 1-2 bits per unassigned index). For
  1372. // instance, if you allocate an array of size 5 and assign a[2] = <big
  1373. // struct>, then a[2] will take up a lot of memory but a[0], a[1],
  1374. // a[3], and a[4] will not. Array elements that have a value are
  1375. // called "assigned". Array elements that have no value yet, or have
  1376. // had their value cleared using erase() or clear(), are called
  1377. // "unassigned".
  1378. //
  1379. // Unassigned values seem to have the default value of T (see below).
  1380. // Nevertheless, there is a difference between an unassigned index and
  1381. // one explicitly assigned the value of T(). The latter is considered
  1382. // assigned.
  1383. //
  1384. // Access to an array element is constant time, as is insertion and
  1385. // deletion. Insertion and deletion may be fairly slow, however:
  1386. // because of this container's memory economy, each insert and delete
  1387. // causes a memory reallocation.
  1388. //
  1389. // NOTE: You should not test(), get(), or set() any index that is
  1390. // greater than sparsetable.size(). If you need to do that, call
  1391. // resize() first.
  1392. //
  1393. // --- Template parameters
  1394. // PARAMETER DESCRIPTION DEFAULT
  1395. // T The value of the array: the type of --
  1396. // object that is stored in the array.
  1397. //
  1398. // Alloc: Allocator to use to allocate memory. libc_allocator_with_realloc
  1399. //
  1400. // --- Model of
  1401. // Random Access Container
  1402. //
  1403. // --- Type requirements
  1404. // T must be Copy Constructible. It need not be Assignable.
  1405. //
  1406. // --- Public base classes
  1407. // None.
  1408. //
  1409. // --- Members
  1410. //
  1411. // [*] All iterators are const in a sparsetable (though nonempty_iterators
  1412. // may not be). Use get() and set() to assign values, not iterators.
  1413. //
  1414. // [+] iterators are random-access iterators. nonempty_iterators are
  1415. // bidirectional iterators.
  1416. // [*] If you shrink a sparsetable using resize(), assigned elements
  1417. // past the end of the table are removed using erase(). If you grow
  1418. // a sparsetable, new unassigned indices are created.
  1419. //
  1420. // [+] Note that operator[] returns a const reference. You must use
  1421. // set() to change the value of a table element.
  1422. //
  1423. // [!] Unassignment also calls the destructor.
  1424. //
  1425. // Iterators are invalidated whenever an item is inserted or
  1426. // deleted (ie set() or erase() is used) or when the size of
  1427. // the table changes (ie resize() or clear() is used).
  1428. // ---------------------------------------------------------------------------
  1429. // type_traits we need
  1430. // ---------------------------------------------------------------------------
  1431. template<class T, T v>
  1432. struct integral_constant { static const T value = v; };
  1433. template <class T, T v> const T integral_constant<T, v>::value;
  1434. typedef integral_constant<bool, true> true_type;
  1435. typedef integral_constant<bool, false> false_type;
  1436. template<typename T, typename U> struct is_same : public false_type { };
  1437. template<typename T> struct is_same<T, T> : public true_type { };
  1438. template<typename T> struct remove_const { typedef T type; };
  1439. template<typename T> struct remove_const<T const> { typedef T type; };
  1440. template<typename T> struct remove_volatile { typedef T type; };
  1441. template<typename T> struct remove_volatile<T volatile> { typedef T type; };
  1442. template<typename T> struct remove_cv {
  1443. typedef typename remove_const<typename remove_volatile<T>::type>::type type;
  1444. };
  1445. // ---------------- is_integral ----------------------------------------
  1446. template <class T> struct is_integral;
  1447. template <class T> struct is_integral : false_type { };
  1448. template<> struct is_integral<bool> : true_type { };
  1449. template<> struct is_integral<char> : true_type { };
  1450. template<> struct is_integral<unsigned char> : true_type { };
  1451. template<> struct is_integral<signed char> : true_type { };
  1452. template<> struct is_integral<short> : true_type { };
  1453. template<> struct is_integral<unsigned short> : true_type { };
  1454. template<> struct is_integral<int> : true_type { };
  1455. template<> struct is_integral<unsigned int> : true_type { };
  1456. template<> struct is_integral<long> : true_type { };
  1457. template<> struct is_integral<unsigned long> : true_type { };
  1458. #ifdef SPP_HAS_LONG_LONG
  1459. template<> struct is_integral<long long> : true_type { };
  1460. template<> struct is_integral<unsigned long long> : true_type { };
  1461. #endif
  1462. template <class T> struct is_integral<const T> : is_integral<T> { };
  1463. template <class T> struct is_integral<volatile T> : is_integral<T> { };
  1464. template <class T> struct is_integral<const volatile T> : is_integral<T> { };
  1465. // ---------------- is_floating_point ----------------------------------------
  1466. template <class T> struct is_floating_point;
  1467. template <class T> struct is_floating_point : false_type { };
  1468. template<> struct is_floating_point<float> : true_type { };
  1469. template<> struct is_floating_point<double> : true_type { };
  1470. template<> struct is_floating_point<long double> : true_type { };
  1471. template <class T> struct is_floating_point<const T> : is_floating_point<T> { };
  1472. template <class T> struct is_floating_point<volatile T> : is_floating_point<T> { };
  1473. template <class T> struct is_floating_point<const volatile T> : is_floating_point<T> { };
  1474. // ---------------- is_pointer ----------------------------------------
  1475. template <class T> struct is_pointer;
  1476. template <class T> struct is_pointer : false_type { };
  1477. template <class T> struct is_pointer<T*> : true_type { };
  1478. template <class T> struct is_pointer<const T> : is_pointer<T> { };
  1479. template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
  1480. template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
  1481. // ---------------- is_reference ----------------------------------------
  1482. template <class T> struct is_reference;
  1483. template<typename T> struct is_reference : false_type {};
  1484. template<typename T> struct is_reference<T&> : true_type {};
  1485. // ---------------- is_relocatable ----------------------------------------
  1486. // relocatable values can be moved around in memory using memcpy and remain
  1487. // correct. Most types are relocatable, an example of a type who is not would
  1488. // be a struct which contains a pointer to a buffer inside itself - this is the
  1489. // case for std::string in gcc 5.
  1490. // ------------------------------------------------------------------------
  1491. template <class T> struct is_relocatable;
  1492. template <class T> struct is_relocatable :
  1493. integral_constant<bool, (is_integral<T>::value || is_floating_point<T>::value)>
  1494. { };
  1495. template<int S, int H> struct is_relocatable<HashObject<S, H> > : true_type { };
  1496. template <class T> struct is_relocatable<const T> : is_relocatable<T> { };
  1497. template <class T> struct is_relocatable<volatile T> : is_relocatable<T> { };
  1498. template <class T> struct is_relocatable<const volatile T> : is_relocatable<T> { };
  1499. template <class A, int N> struct is_relocatable<A[N]> : is_relocatable<A> { };
  1500. template <class T, class U> struct is_relocatable<std::pair<T, U> > :
  1501. integral_constant<bool, (is_relocatable<T>::value && is_relocatable<U>::value)>
  1502. { };
  1503. // ---------------------------------------------------------------------------
  1504. // Our iterator as simple as iterators can be: basically it's just
  1505. // the index into our table. Dereference, the only complicated
  1506. // thing, we punt to the table class. This just goes to show how
  1507. // much machinery STL requires to do even the most trivial tasks.
  1508. //
  1509. // A NOTE ON ASSIGNING:
  1510. // A sparse table does not actually allocate memory for entries
  1511. // that are not filled. Because of this, it becomes complicated
  1512. // to have a non-const iterator: we don't know, if the iterator points
  1513. // to a not-filled bucket, whether you plan to fill it with something
  1514. // or whether you plan to read its value (in which case you'll get
  1515. // the default bucket value). Therefore, while we can define const
  1516. // operations in a pretty 'normal' way, for non-const operations, we
  1517. // define something that returns a helper object with operator= and
  1518. // operator& that allocate a bucket lazily. We use this for table[]
  1519. // and also for regular table iterators.
  1520. // ---------------------------------------------------------------------------
  1521. // ---------------------------------------------------------------------------
  1522. // Our iterator as simple as iterators can be: basically it's just
  1523. // the index into our table. Dereference, the only complicated
  1524. // thing, we punt to the table class. This just goes to show how
  1525. // much machinery STL requires to do even the most trivial tasks.
  1526. //
  1527. // By templatizing over tabletype, we have one iterator type which
  1528. // we can use for both sparsetables and sparsebins. In fact it
  1529. // works on any class that allows size() and operator[] (eg vector),
  1530. // as long as it does the standard STL typedefs too (eg value_type).
  1531. // ---------------------------------------------------------------------------
  1532. // ---------------------------------------------------------------------------
  1533. template <class tabletype>
  1534. class table_iterator
  1535. {
  1536. public:
  1537. typedef table_iterator iterator;
  1538. typedef std::random_access_iterator_tag iterator_category;
  1539. typedef typename tabletype::value_type value_type;
  1540. typedef typename tabletype::difference_type difference_type;
  1541. typedef typename tabletype::size_type size_type;
  1542. explicit table_iterator(tabletype *tbl = 0, size_type p = 0) :
  1543. table(tbl), pos(p)
  1544. { }
  1545. // Helper function to assert things are ok; eg pos is still in range
  1546. void check() const
  1547. {
  1548. assert(table);
  1549. assert(pos <= table->size());
  1550. }
  1551. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1552. // do bounds checking, since STL doesn't consider that its job. :-)
  1553. iterator& operator+=(size_type t) { pos += t; check(); return *this; }
  1554. iterator& operator-=(size_type t) { pos -= t; check(); return *this; }
  1555. iterator& operator++() { ++pos; check(); return *this; }
  1556. iterator& operator--() { --pos; check(); return *this; }
  1557. iterator operator++(int)
  1558. {
  1559. iterator tmp(*this); // for x++
  1560. ++pos; check(); return tmp;
  1561. }
  1562. iterator operator--(int)
  1563. {
  1564. iterator tmp(*this); // for x--
  1565. --pos; check(); return tmp;
  1566. }
  1567. iterator operator+(difference_type i) const
  1568. {
  1569. iterator tmp(*this);
  1570. tmp += i; return tmp;
  1571. }
  1572. iterator operator-(difference_type i) const
  1573. {
  1574. iterator tmp(*this);
  1575. tmp -= i; return tmp;
  1576. }
  1577. difference_type operator-(iterator it) const
  1578. { // for "x = it2 - it"
  1579. assert(table == it.table);
  1580. return pos - it.pos;
  1581. }
  1582. // Comparisons.
  1583. bool operator==(const iterator& it) const
  1584. {
  1585. return table == it.table && pos == it.pos;
  1586. }
  1587. bool operator<(const iterator& it) const
  1588. {
  1589. assert(table == it.table); // life is bad bad bad otherwise
  1590. return pos < it.pos;
  1591. }
  1592. bool operator!=(const iterator& it) const { return !(*this == it); }
  1593. bool operator<=(const iterator& it) const { return !(it < *this); }
  1594. bool operator>(const iterator& it) const { return it < *this; }
  1595. bool operator>=(const iterator& it) const { return !(*this < it); }
  1596. // Here's the info we actually need to be an iterator
  1597. tabletype *table; // so we can dereference and bounds-check
  1598. size_type pos; // index into the table
  1599. };
  1600. // ---------------------------------------------------------------------------
  1601. // ---------------------------------------------------------------------------
  1602. template <class tabletype>
  1603. class const_table_iterator
  1604. {
  1605. public:
  1606. typedef table_iterator<tabletype> iterator;
  1607. typedef const_table_iterator const_iterator;
  1608. typedef std::random_access_iterator_tag iterator_category;
  1609. typedef typename tabletype::value_type value_type;
  1610. typedef typename tabletype::difference_type difference_type;
  1611. typedef typename tabletype::size_type size_type;
  1612. typedef typename tabletype::const_reference reference; // we're const-only
  1613. typedef typename tabletype::const_pointer pointer;
  1614. // The "real" constructor
  1615. const_table_iterator(const tabletype *tbl, size_type p)
  1616. : table(tbl), pos(p) { }
  1617. // The default constructor, used when I define vars of type table::iterator
  1618. const_table_iterator() : table(NULL), pos(0) { }
  1619. // The copy constructor, for when I say table::iterator foo = tbl.begin()
  1620. // Also converts normal iterators to const iterators // not explicit on purpose
  1621. const_table_iterator(const iterator &from)
  1622. : table(from.table), pos(from.pos) { }
  1623. // The default destructor is fine; we don't define one
  1624. // The default operator= is fine; we don't define one
  1625. // The main thing our iterator does is dereference. If the table entry
  1626. // we point to is empty, we return the default value type.
  1627. reference operator*() const { return (*table)[pos]; }
  1628. pointer operator->() const { return &(operator*()); }
  1629. // Helper function to assert things are ok; eg pos is still in range
  1630. void check() const
  1631. {
  1632. assert(table);
  1633. assert(pos <= table->size());
  1634. }
  1635. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1636. // do bounds checking, since STL doesn't consider that its job. :-)
  1637. const_iterator& operator+=(size_type t) { pos += t; check(); return *this; }
  1638. const_iterator& operator-=(size_type t) { pos -= t; check(); return *this; }
  1639. const_iterator& operator++() { ++pos; check(); return *this; }
  1640. const_iterator& operator--() { --pos; check(); return *this; }
  1641. const_iterator operator++(int) { const_iterator tmp(*this); // for x++
  1642. ++pos; check(); return tmp; }
  1643. const_iterator operator--(int) { const_iterator tmp(*this); // for x--
  1644. --pos; check(); return tmp; }
  1645. const_iterator operator+(difference_type i) const
  1646. {
  1647. const_iterator tmp(*this);
  1648. tmp += i;
  1649. return tmp;
  1650. }
  1651. const_iterator operator-(difference_type i) const
  1652. {
  1653. const_iterator tmp(*this);
  1654. tmp -= i;
  1655. return tmp;
  1656. }
  1657. difference_type operator-(const_iterator it) const
  1658. { // for "x = it2 - it"
  1659. assert(table == it.table);
  1660. return pos - it.pos;
  1661. }
  1662. reference operator[](difference_type n) const
  1663. {
  1664. return *(*this + n); // simple though not totally efficient
  1665. }
  1666. // Comparisons.
  1667. bool operator==(const const_iterator& it) const
  1668. {
  1669. return table == it.table && pos == it.pos;
  1670. }
  1671. bool operator<(const const_iterator& it) const
  1672. {
  1673. assert(table == it.table); // life is bad bad bad otherwise
  1674. return pos < it.pos;
  1675. }
  1676. bool operator!=(const const_iterator& it) const { return !(*this == it); }
  1677. bool operator<=(const const_iterator& it) const { return !(it < *this); }
  1678. bool operator>(const const_iterator& it) const { return it < *this; }
  1679. bool operator>=(const const_iterator& it) const { return !(*this < it); }
  1680. // Here's the info we actually need to be an iterator
  1681. const tabletype *table; // so we can dereference and bounds-check
  1682. size_type pos; // index into the table
  1683. };
  1684. // ---------------------------------------------------------------------------
  1685. // This is a 2-D iterator. You specify a begin and end over a list
  1686. // of *containers*. We iterate over each container by iterating over
  1687. // it. It's actually simple:
  1688. // VECTOR.begin() VECTOR[0].begin() --------> VECTOR[0].end() ---,
  1689. // | ________________________________________________/
  1690. // | \_> VECTOR[1].begin() --------> VECTOR[1].end() -,
  1691. // | ___________________________________________________/
  1692. // v \_> ......
  1693. // VECTOR.end()
  1694. //
  1695. // It's impossible to do random access on one of these things in constant
  1696. // time, so it's just a bidirectional iterator.
  1697. //
  1698. // Unfortunately, because we need to use this for a non-empty iterator,
  1699. // we use ne_begin() and ne_end() instead of begin() and end()
  1700. // (though only going across, not down).
  1701. // ---------------------------------------------------------------------------
  1702. // ---------------------------------------------------------------------------
  1703. // ---------------------------------------------------------------------------
  1704. template <class T, class row_it, class col_it, class iter_type>
  1705. class Two_d_iterator : public std::iterator<iter_type, T>
  1706. {
  1707. public:
  1708. typedef Two_d_iterator iterator;
  1709. // T can be std::pair<K, V>, but we need to return std::pair<const K, V>
  1710. // ---------------------------------------------------------------------
  1711. typedef typename spp_::cvt<T>::type value_type;
  1712. typedef value_type& reference;
  1713. typedef value_type* pointer;
  1714. explicit Two_d_iterator(row_it curr) : row_current(curr), col_current(0)
  1715. {
  1716. if (row_current && !row_current->is_marked())
  1717. {
  1718. col_current = row_current->ne_begin();
  1719. advance_past_end(); // in case cur->begin() == cur->end()
  1720. }
  1721. }
  1722. explicit Two_d_iterator(row_it curr, col_it col) : row_current(curr), col_current(col)
  1723. {
  1724. assert(col);
  1725. }
  1726. // The default constructor
  1727. Two_d_iterator() : row_current(0), col_current(0) { }
  1728. // Need this explicitly so we can convert normal iterators <=> const iterators
  1729. // not explicit on purpose
  1730. // ---------------------------------------------------------------------------
  1731. template <class T2, class row_it2, class col_it2, class iter_type2>
  1732. Two_d_iterator(const Two_d_iterator<T2, row_it2, col_it2, iter_type2>& it) :
  1733. row_current (*(row_it *)&it.row_current),
  1734. col_current (*(col_it *)&it.col_current)
  1735. { }
  1736. // The default destructor is fine; we don't define one
  1737. // The default operator= is fine; we don't define one
  1738. reference operator*() const { return *(col_current); }
  1739. pointer operator->() const { return &(operator*()); }
  1740. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1741. // do bounds checking, since STL doesn't consider that its job. :-)
  1742. // NOTE: this is not amortized constant time! What do we do about it?
  1743. // ------------------------------------------------------------------
  1744. void advance_past_end()
  1745. {
  1746. // used when col_current points to end()
  1747. while (col_current == row_current->ne_end())
  1748. {
  1749. // end of current row
  1750. // ------------------
  1751. ++row_current; // go to beginning of next
  1752. if (!row_current->is_marked()) // col is irrelevant at end
  1753. col_current = row_current->ne_begin();
  1754. else
  1755. break; // don't go past row_end
  1756. }
  1757. }
  1758. friend size_t operator-(iterator l, iterator f)
  1759. {
  1760. if (f.row_current->is_marked())
  1761. return 0;
  1762. size_t diff(0);
  1763. while (f != l)
  1764. {
  1765. ++diff;
  1766. ++f;
  1767. }
  1768. return diff;
  1769. }
  1770. iterator& operator++()
  1771. {
  1772. // assert(!row_current->is_marked()); // how to ++ from there?
  1773. ++col_current;
  1774. advance_past_end(); // in case col_current is at end()
  1775. return *this;
  1776. }
  1777. iterator& operator--()
  1778. {
  1779. while (row_current->is_marked() ||
  1780. col_current == row_current->ne_begin())
  1781. {
  1782. --row_current;
  1783. col_current = row_current->ne_end(); // this is 1 too far
  1784. }
  1785. --col_current;
  1786. return *this;
  1787. }
  1788. iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
  1789. iterator operator--(int) { iterator tmp(*this); --*this; return tmp; }
  1790. // Comparisons.
  1791. bool operator==(const iterator& it) const
  1792. {
  1793. return (row_current == it.row_current &&
  1794. (!row_current || row_current->is_marked() || col_current == it.col_current));
  1795. }
  1796. bool operator!=(const iterator& it) const { return !(*this == it); }
  1797. // Here's the info we actually need to be an iterator
  1798. // These need to be public so we convert from iterator to const_iterator
  1799. // ---------------------------------------------------------------------
  1800. row_it row_current;
  1801. col_it col_current;
  1802. };
  1803. // ---------------------------------------------------------------------------
  1804. // ---------------------------------------------------------------------------
  1805. template <class T, class row_it, class col_it, class iter_type, class Alloc>
  1806. class Two_d_destructive_iterator : public Two_d_iterator<T, row_it, col_it, iter_type>
  1807. {
  1808. public:
  1809. typedef Two_d_destructive_iterator iterator;
  1810. Two_d_destructive_iterator(Alloc &alloc, row_it curr) :
  1811. _alloc(alloc)
  1812. {
  1813. this->row_current = curr;
  1814. this->col_current = 0;
  1815. if (this->row_current && !this->row_current->is_marked())
  1816. {
  1817. this->col_current = this->row_current->ne_begin();
  1818. advance_past_end(); // in case cur->begin() == cur->end()
  1819. }
  1820. }
  1821. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1822. // do bounds checking, since STL doesn't consider that its job. :-)
  1823. // NOTE: this is not amortized constant time! What do we do about it?
  1824. // ------------------------------------------------------------------
  1825. void advance_past_end()
  1826. {
  1827. // used when col_current points to end()
  1828. while (this->col_current == this->row_current->ne_end())
  1829. {
  1830. this->row_current->clear(_alloc, true); // This is what differs from non-destructive iterators above
  1831. // end of current row
  1832. // ------------------
  1833. ++this->row_current; // go to beginning of next
  1834. if (!this->row_current->is_marked()) // col is irrelevant at end
  1835. this->col_current = this->row_current->ne_begin();
  1836. else
  1837. break; // don't go past row_end
  1838. }
  1839. }
  1840. iterator& operator++()
  1841. {
  1842. // assert(!this->row_current->is_marked()); // how to ++ from there?
  1843. ++this->col_current;
  1844. advance_past_end(); // in case col_current is at end()
  1845. return *this;
  1846. }
  1847. private:
  1848. Two_d_destructive_iterator& operator=(const Two_d_destructive_iterator &o);
  1849. Alloc &_alloc;
  1850. };
  1851. // ---------------------------------------------------------------------------
  1852. // ---------------------------------------------------------------------------
  1853. static const char spp_bits_in[256] = {
  1854. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
  1855. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1856. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1857. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1858. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1859. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1860. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1861. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1862. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1863. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1864. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1865. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1866. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1867. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1868. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1869. 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
  1870. };
  1871. static inline uint32_t s_spp_popcount_default_lut(uint32_t i)
  1872. {
  1873. uint32_t res = static_cast<uint32_t>(spp_bits_in[i & 0xFF]);
  1874. res += static_cast<uint32_t>(spp_bits_in[(i >> 8) & 0xFF]);
  1875. res += static_cast<uint32_t>(spp_bits_in[(i >> 16) & 0xFF]);
  1876. res += static_cast<uint32_t>(spp_bits_in[i >> 24]);
  1877. return res;
  1878. }
  1879. static inline uint32_t s_spp_popcount_default_lut(uint64_t i)
  1880. {
  1881. uint32_t res = static_cast<uint32_t>(spp_bits_in[i & 0xFF]);
  1882. res += static_cast<uint32_t>(spp_bits_in[(i >> 8) & 0xFF]);
  1883. res += static_cast<uint32_t>(spp_bits_in[(i >> 16) & 0xFF]);
  1884. res += static_cast<uint32_t>(spp_bits_in[(i >> 24) & 0xFF]);
  1885. res += static_cast<uint32_t>(spp_bits_in[(i >> 32) & 0xFF]);
  1886. res += static_cast<uint32_t>(spp_bits_in[(i >> 40) & 0xFF]);
  1887. res += static_cast<uint32_t>(spp_bits_in[(i >> 48) & 0xFF]);
  1888. res += static_cast<uint32_t>(spp_bits_in[i >> 56]);
  1889. return res;
  1890. }
  1891. // faster than the lookup table (LUT)
  1892. // ----------------------------------
  1893. static inline uint32_t s_spp_popcount_default(uint32_t i)
  1894. {
  1895. i = i - ((i >> 1) & 0x55555555);
  1896. i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
  1897. return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
  1898. }
  1899. // faster than the lookup table (LUT)
  1900. // ----------------------------------
  1901. static inline uint32_t s_spp_popcount_default(uint64_t x)
  1902. {
  1903. const uint64_t m1 = uint64_t(0x5555555555555555); // binary: 0101...
  1904. const uint64_t m2 = uint64_t(0x3333333333333333); // binary: 00110011..
  1905. const uint64_t m4 = uint64_t(0x0f0f0f0f0f0f0f0f); // binary: 4 zeros, 4 ones ...
  1906. const uint64_t h01 = uint64_t(0x0101010101010101); // the sum of 256 to the power of 0,1,2,3...
  1907. x -= (x >> 1) & m1; // put count of each 2 bits into those 2 bits
  1908. x = (x & m2) + ((x >> 2) & m2); // put count of each 4 bits into those 4 bits
  1909. x = (x + (x >> 4)) & m4; // put count of each 8 bits into those 8 bits
  1910. return (x * h01)>>56; // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24)+...
  1911. }
  1912. #if defined(SPP_POPCNT_CHECK)
  1913. static inline bool spp_popcount_check()
  1914. {
  1915. int cpuInfo[4] = { -1 };
  1916. spp_cpuid(cpuInfo, 1);
  1917. if (cpuInfo[2] & (1 << 23))
  1918. return true; // means SPP_POPCNT supported
  1919. return false;
  1920. }
  1921. #endif
  1922. #if defined(SPP_POPCNT_CHECK) && defined(SPP_POPCNT)
  1923. static inline uint32_t spp_popcount(uint32_t i)
  1924. {
  1925. static const bool s_ok = spp_popcount_check();
  1926. return s_ok ? SPP_POPCNT(i) : s_spp_popcount_default(i);
  1927. }
  1928. #else
  1929. static inline uint32_t spp_popcount(uint32_t i)
  1930. {
  1931. #if defined(SPP_POPCNT)
  1932. return static_cast<uint32_t>(SPP_POPCNT(i));
  1933. #else
  1934. return s_spp_popcount_default(i);
  1935. #endif
  1936. }
  1937. #endif
  1938. #if defined(SPP_POPCNT_CHECK) && defined(SPP_POPCNT64)
  1939. static inline uint32_t spp_popcount(uint64_t i)
  1940. {
  1941. static const bool s_ok = spp_popcount_check();
  1942. return s_ok ? (uint32_t)SPP_POPCNT64(i) : s_spp_popcount_default(i);
  1943. }
  1944. #else
  1945. static inline uint32_t spp_popcount(uint64_t i)
  1946. {
  1947. #if defined(SPP_POPCNT64)
  1948. return static_cast<uint32_t>(SPP_POPCNT64(i));
  1949. #elif 1
  1950. return s_spp_popcount_default(i);
  1951. #endif
  1952. }
  1953. #endif
  1954. // ---------------------------------------------------------------------------
  1955. // SPARSE-TABLE
  1956. // ------------
  1957. // The idea is that a table with (logically) t buckets is divided
  1958. // into t/M *groups* of M buckets each. (M is a constant, typically
  1959. // 32) Each group is stored sparsely.
  1960. // Thus, inserting into the table causes some array to grow, which is
  1961. // slow but still constant time. Lookup involves doing a
  1962. // logical-position-to-sparse-position lookup, which is also slow but
  1963. // constant time. The larger M is, the slower these operations are
  1964. // but the less overhead (slightly).
  1965. //
  1966. // To store the sparse array, we store a bitmap B, where B[i] = 1 iff
  1967. // bucket i is non-empty. Then to look up bucket i we really look up
  1968. // array[# of 1s before i in B]. This is constant time for fixed M.
  1969. //
  1970. // Terminology: the position of an item in the overall table (from
  1971. // 1 .. t) is called its "location." The logical position in a group
  1972. // (from 1 .. M) is called its "position." The actual location in
  1973. // the array (from 1 .. # of non-empty buckets in the group) is
  1974. // called its "offset."
  1975. // ---------------------------------------------------------------------------
  1976. template <class T, class Alloc>
  1977. class sparsegroup
  1978. {
  1979. public:
  1980. // Basic types
  1981. typedef typename spp::cvt<T>::type value_type;
  1982. typedef Alloc allocator_type;
  1983. typedef value_type& reference;
  1984. typedef const value_type& const_reference;
  1985. typedef value_type* pointer;
  1986. typedef const value_type* const_pointer;
  1987. typedef uint8_t size_type; // max # of buckets
  1988. // These are our special iterators, that go over non-empty buckets in a
  1989. // group. These aren't const-only because you can change non-empty bcks.
  1990. // ---------------------------------------------------------------------
  1991. typedef pointer ne_iterator;
  1992. typedef const_pointer const_ne_iterator;
  1993. typedef std::reverse_iterator<ne_iterator> reverse_ne_iterator;
  1994. typedef std::reverse_iterator<const_ne_iterator> const_reverse_ne_iterator;
  1995. // We'll have versions for our special non-empty iterator too
  1996. // ----------------------------------------------------------
  1997. ne_iterator ne_begin() { return reinterpret_cast<pointer>(_group); }
  1998. const_ne_iterator ne_begin() const { return reinterpret_cast<pointer>(_group); }
  1999. const_ne_iterator ne_cbegin() const { return reinterpret_cast<pointer>(_group); }
  2000. ne_iterator ne_end() { return reinterpret_cast<pointer>(_group + _num_items()); }
  2001. const_ne_iterator ne_end() const { return reinterpret_cast<pointer>(_group + _num_items()); }
  2002. const_ne_iterator ne_cend() const { return reinterpret_cast<pointer>(_group + _num_items()); }
  2003. reverse_ne_iterator ne_rbegin() { return reverse_ne_iterator(ne_end()); }
  2004. const_reverse_ne_iterator ne_rbegin() const { return const_reverse_ne_iterator(ne_cend()); }
  2005. const_reverse_ne_iterator ne_crbegin() const { return const_reverse_ne_iterator(ne_cend()); }
  2006. reverse_ne_iterator ne_rend() { return reverse_ne_iterator(ne_begin()); }
  2007. const_reverse_ne_iterator ne_rend() const { return const_reverse_ne_iterator(ne_cbegin()); }
  2008. const_reverse_ne_iterator ne_crend() const { return const_reverse_ne_iterator(ne_cbegin()); }
  2009. private:
  2010. // T can be std::pair<K, V>, but we need to return std::pair<const K, V>
  2011. // ---------------------------------------------------------------------
  2012. typedef T mutable_value_type;
  2013. typedef mutable_value_type& mutable_reference;
  2014. typedef const mutable_value_type& const_mutable_reference;
  2015. typedef mutable_value_type* mutable_pointer;
  2016. typedef const mutable_value_type* const_mutable_pointer;
  2017. #define spp_mutable_ref(x) (*(reinterpret_cast<mutable_pointer>(&(x))))
  2018. #define spp_const_mutable_ref(x) (*(reinterpret_cast<const_mutable_pointer>(&(x))))
  2019. typedef typename Alloc::template rebind<T>::other value_alloc_type;
  2020. bool _bmtest(size_type i) const { return !!(_bitmap & (static_cast<group_bm_type>(1) << i)); }
  2021. void _bmset(size_type i) { _bitmap |= static_cast<group_bm_type>(1) << i; }
  2022. void _bmclear(size_type i) { _bitmap &= ~(static_cast<group_bm_type>(1) << i); }
  2023. bool _bme_test(size_type i) const { return !!(_bm_erased & (static_cast<group_bm_type>(1) << i)); }
  2024. void _bme_set(size_type i) { _bm_erased |= static_cast<group_bm_type>(1) << i; }
  2025. void _bme_clear(size_type i) { _bm_erased &= ~(static_cast<group_bm_type>(1) << i); }
  2026. bool _bmtest_strict(size_type i) const
  2027. { return !!((_bitmap | _bm_erased) & (static_cast<group_bm_type>(1) << i)); }
  2028. static uint32_t _sizing(uint32_t n)
  2029. {
  2030. #if !defined(SPP_ALLOC_SZ) || (SPP_ALLOC_SZ == 0)
  2031. // aggressive allocation first, then decreasing as sparsegroups fill up
  2032. // --------------------------------------------------------------------
  2033. static uint8_t s_alloc_batch_sz[SPP_GROUP_SIZE] = { 0 };
  2034. if (!s_alloc_batch_sz[0])
  2035. {
  2036. // 32 bit bitmap
  2037. // ........ .... .... .. .. .. .. . . . . . . . .
  2038. // 8 12 16 18 20 22 24 25 26 ... 32
  2039. // ------------------------------------------------------
  2040. uint8_t group_sz = SPP_GROUP_SIZE / 4;
  2041. uint8_t group_start_alloc = SPP_GROUP_SIZE / 8; //4;
  2042. uint8_t alloc_sz = group_start_alloc;
  2043. for (int i=0; i<4; ++i)
  2044. {
  2045. for (int j=0; j<group_sz; ++j)
  2046. {
  2047. if (j && j % group_start_alloc == 0)
  2048. alloc_sz += group_start_alloc;
  2049. s_alloc_batch_sz[i * group_sz + j] = alloc_sz;
  2050. }
  2051. if (group_start_alloc > 2)
  2052. group_start_alloc /= 2;
  2053. alloc_sz += group_start_alloc;
  2054. }
  2055. }
  2056. return n ? static_cast<uint32_t>(s_alloc_batch_sz[n-1]) : 0; // more aggressive alloc at the beginning
  2057. #elif (SPP_ALLOC_SZ == 1)
  2058. // use as little memory as possible - slowest insert/delete in table
  2059. // -----------------------------------------------------------------
  2060. return n;
  2061. #else
  2062. // decent compromise when SPP_ALLOC_SZ == 2
  2063. // ----------------------------------------
  2064. static size_type sz_minus_1 = SPP_ALLOC_SZ - 1;
  2065. return (n + sz_minus_1) & ~sz_minus_1;
  2066. #endif
  2067. }
  2068. mutable_pointer _allocate_group(Alloc &alloc, uint32_t n /* , bool tight = false */)
  2069. {
  2070. // ignore tight since we don't store num_alloc
  2071. // num_alloc = (uint8_t)(tight ? n : _sizing(n));
  2072. uint32_t num_alloc = (uint8_t)_sizing(n);
  2073. _set_num_alloc(num_alloc);
  2074. mutable_pointer retval = alloc.allocate(static_cast<size_type>(num_alloc));
  2075. if (retval == NULL)
  2076. {
  2077. // the allocator is supposed to throw an exception if the allocation fails.
  2078. fprintf(stderr, "sparsehash FATAL ERROR: failed to allocate %d groups\n", num_alloc);
  2079. exit(1);
  2080. }
  2081. return retval;
  2082. }
  2083. void _free_group(Alloc &alloc, uint32_t num_alloc)
  2084. {
  2085. if (_group)
  2086. {
  2087. uint32_t num_buckets = _num_items();
  2088. if (num_buckets)
  2089. {
  2090. mutable_pointer end_it = _group + num_buckets;
  2091. for (mutable_pointer p = _group; p != end_it; ++p)
  2092. p->~mutable_value_type();
  2093. }
  2094. alloc.deallocate(_group, (typename allocator_type::size_type)num_alloc);
  2095. _group = NULL;
  2096. }
  2097. }
  2098. // private because should not be called - no allocator!
  2099. sparsegroup &operator=(const sparsegroup& x);
  2100. static size_type _pos_to_offset(group_bm_type bm, size_type pos)
  2101. {
  2102. //return (size_type)((uint32_t)~((int32_t(-1) + pos) >> 31) & spp_popcount(bm << (SPP_GROUP_SIZE - pos)));
  2103. //return (size_type)(pos ? spp_popcount(bm << (SPP_GROUP_SIZE - pos)) : 0);
  2104. return static_cast<size_type>(spp_popcount(bm & ((static_cast<group_bm_type>(1) << pos) - 1)));
  2105. }
  2106. public:
  2107. // get_iter() in sparsetable needs it
  2108. size_type pos_to_offset(size_type pos) const
  2109. {
  2110. return _pos_to_offset(_bitmap, pos);
  2111. }
  2112. #ifdef _MSC_VER
  2113. #pragma warning(push)
  2114. #pragma warning(disable : 4146)
  2115. #endif
  2116. // Returns the (logical) position in the bm[] array, i, such that
  2117. // bm[i] is the offset-th set bit in the array. It is the inverse
  2118. // of pos_to_offset. get_pos() uses this function to find the index
  2119. // of an ne_iterator in the table. Bit-twiddling from
  2120. // http://hackersdelight.org/basics.pdf
  2121. // -----------------------------------------------------------------
  2122. static size_type offset_to_pos(group_bm_type bm, size_type offset)
  2123. {
  2124. for (; offset > 0; offset--)
  2125. bm &= (bm-1); // remove right-most set bit
  2126. // Clear all bits to the left of the rightmost bit (the &),
  2127. // and then clear the rightmost bit but set all bits to the
  2128. // right of it (the -1).
  2129. // --------------------------------------------------------
  2130. bm = (bm & -bm) - 1;
  2131. return static_cast<size_type>(spp_popcount(bm));
  2132. }
  2133. #ifdef _MSC_VER
  2134. #pragma warning(pop)
  2135. #endif
  2136. size_type offset_to_pos(size_type offset) const
  2137. {
  2138. return offset_to_pos(_bitmap, offset);
  2139. }
  2140. public:
  2141. // Constructors -- default and copy -- and destructor
  2142. explicit sparsegroup() :
  2143. _group(0), _bitmap(0), _bm_erased(0)
  2144. {
  2145. _set_num_items(0);
  2146. _set_num_alloc(0);
  2147. }
  2148. sparsegroup(const sparsegroup& x) :
  2149. _group(0), _bitmap(x._bitmap), _bm_erased(x._bm_erased)
  2150. {
  2151. _set_num_items(0);
  2152. _set_num_alloc(0);
  2153. assert(_group == 0); if (_group) exit(1);
  2154. }
  2155. sparsegroup(const sparsegroup& x, allocator_type& a) :
  2156. _group(0), _bitmap(x._bitmap), _bm_erased(x._bm_erased)
  2157. {
  2158. _set_num_items(0);
  2159. _set_num_alloc(0);
  2160. uint32_t num_items = x._num_items();
  2161. if (num_items)
  2162. {
  2163. _group = _allocate_group(a, num_items /* , true */);
  2164. _set_num_items(num_items);
  2165. std::uninitialized_copy(x._group, x._group + num_items, _group);
  2166. }
  2167. }
  2168. ~sparsegroup() { assert(_group == 0); if (_group) exit(1); }
  2169. void destruct(allocator_type& a) { _free_group(a, _num_alloc()); }
  2170. // Many STL algorithms use swap instead of copy constructors
  2171. void swap(sparsegroup& x)
  2172. {
  2173. using std::swap;
  2174. swap(_group, x._group);
  2175. swap(_bitmap, x._bitmap);
  2176. swap(_bm_erased, x._bm_erased);
  2177. #ifdef SPP_STORE_NUM_ITEMS
  2178. swap(_num_buckets, x._num_buckets);
  2179. swap(_num_allocated, x._num_allocated);
  2180. #endif
  2181. }
  2182. // It's always nice to be able to clear a table without deallocating it
  2183. void clear(Alloc &alloc, bool erased)
  2184. {
  2185. _free_group(alloc, _num_alloc());
  2186. _bitmap = 0;
  2187. if (erased)
  2188. _bm_erased = 0;
  2189. _set_num_items(0);
  2190. _set_num_alloc(0);
  2191. }
  2192. // Functions that tell you about size. Alas, these aren't so useful
  2193. // because our table is always fixed size.
  2194. size_type size() const { return static_cast<size_type>(SPP_GROUP_SIZE); }
  2195. size_type max_size() const { return static_cast<size_type>(SPP_GROUP_SIZE); }
  2196. bool empty() const { return false; }
  2197. // We also may want to know how many *used* buckets there are
  2198. size_type num_nonempty() const { return (size_type)_num_items(); }
  2199. // TODO(csilvers): make protected + friend
  2200. // This is used by sparse_hashtable to get an element from the table
  2201. // when we know it exists.
  2202. reference unsafe_get(size_type i) const
  2203. {
  2204. // assert(_bmtest(i));
  2205. return (reference)_group[pos_to_offset(i)];
  2206. }
  2207. typedef std::pair<mutable_pointer, bool> SetResult;
  2208. private:
  2209. typedef spp_::integral_constant<bool,
  2210. (spp_::is_relocatable<value_type>::value &&
  2211. spp_::is_same<allocator_type,
  2212. spp_::libc_allocator_with_realloc<mutable_value_type> >::value)>
  2213. realloc_and_memmove_ok;
  2214. // ------------------------- memory at *p is uninitialized => need to construct
  2215. void _init_val(mutable_value_type *p, reference val)
  2216. {
  2217. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  2218. ::new (p) mutable_value_type(std::move(val));
  2219. #else
  2220. ::new (p) mutable_value_type(val);
  2221. #endif
  2222. }
  2223. // ------------------------- memory at *p is uninitialized => need to construct
  2224. void _init_val(mutable_value_type *p, const_reference val)
  2225. {
  2226. ::new (p) mutable_value_type(val);
  2227. }
  2228. // ------------------------------------------------ memory at *p is initialized
  2229. void _set_val(mutable_value_type *p, reference val)
  2230. {
  2231. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  2232. *p = std::move(val);
  2233. #else
  2234. using std::swap;
  2235. swap(*p, spp_mutable_ref(val));
  2236. #endif
  2237. }
  2238. // ------------------------------------------------ memory at *p is initialized
  2239. void _set_val(mutable_value_type *p, const_reference val)
  2240. {
  2241. *p = spp_const_mutable_ref(val);
  2242. }
  2243. // Our default allocator - try to merge memory buffers
  2244. // right now it uses Google's traits, but we should use something like folly::IsRelocatable
  2245. // return true if the slot was constructed (i.e. contains a valid mutable_value_type
  2246. // ---------------------------------------------------------------------------------
  2247. template <class Val>
  2248. void _set_aux(Alloc &alloc, size_type offset, Val &val, spp_::true_type)
  2249. {
  2250. //static int x=0; if (++x < 10) printf("x\n"); // check we are getting here
  2251. uint32_t num_items = _num_items();
  2252. uint32_t num_alloc = _sizing(num_items);
  2253. if (num_items == num_alloc)
  2254. {
  2255. num_alloc = _sizing(num_items + 1);
  2256. _group = alloc.reallocate(_group, num_alloc);
  2257. _set_num_alloc(num_alloc);
  2258. }
  2259. for (uint32_t i = num_items; i > offset; --i)
  2260. memcpy(_group + i, _group + i-1, sizeof(*_group));
  2261. _init_val(_group + offset, val);
  2262. }
  2263. // Create space at _group[offset], without special assumptions about value_type
  2264. // and allocator_type, with a default value
  2265. // return true if the slot was constructed (i.e. contains a valid mutable_value_type
  2266. // ---------------------------------------------------------------------------------
  2267. template <class Val>
  2268. void _set_aux(Alloc &alloc, size_type offset, Val &val, spp_::false_type)
  2269. {
  2270. uint32_t num_items = _num_items();
  2271. uint32_t num_alloc = _sizing(num_items);
  2272. //assert(num_alloc == (uint32_t)_num_allocated);
  2273. if (num_items < num_alloc)
  2274. {
  2275. // create new object at end and rotate it to position
  2276. _init_val(&_group[num_items], val);
  2277. std::rotate(_group + offset, _group + num_items, _group + num_items + 1);
  2278. return;
  2279. }
  2280. // This is valid because 0 <= offset <= num_items
  2281. mutable_pointer p = _allocate_group(alloc, _sizing(num_items + 1));
  2282. if (offset)
  2283. std::uninitialized_copy(MK_MOVE_IT(_group),
  2284. MK_MOVE_IT(_group + offset),
  2285. p);
  2286. if (num_items > offset)
  2287. std::uninitialized_copy(MK_MOVE_IT(_group + offset),
  2288. MK_MOVE_IT(_group + num_items),
  2289. p + offset + 1);
  2290. _init_val(p + offset, val);
  2291. _free_group(alloc, num_alloc);
  2292. _group = p;
  2293. }
  2294. // ----------------------------------------------------------------------------------
  2295. template <class Val>
  2296. void _set(Alloc &alloc, size_type i, size_type offset, Val &val)
  2297. {
  2298. if (!_bmtest(i))
  2299. {
  2300. _set_aux(alloc, offset, val, realloc_and_memmove_ok());
  2301. _incr_num_items();
  2302. _bmset(i);
  2303. }
  2304. else
  2305. _set_val(&_group[offset], val);
  2306. }
  2307. public:
  2308. // This returns the pointer to the inserted item
  2309. // ---------------------------------------------
  2310. template <class Val>
  2311. pointer set(Alloc &alloc, size_type i, Val &val)
  2312. {
  2313. _bme_clear(i); // in case this was an "erased" location
  2314. size_type offset = pos_to_offset(i);
  2315. _set(alloc, i, offset, val); // may change _group pointer
  2316. return (pointer)(_group + offset);
  2317. }
  2318. // We let you see if a bucket is non-empty without retrieving it
  2319. // -------------------------------------------------------------
  2320. bool test(size_type i) const
  2321. {
  2322. return _bmtest(i);
  2323. }
  2324. // also tests for erased values
  2325. // ----------------------------
  2326. bool test_strict(size_type i) const
  2327. {
  2328. return _bmtest_strict(i);
  2329. }
  2330. private:
  2331. // Shrink the array, assuming value_type has trivial copy
  2332. // constructor and destructor, and the allocator_type is the default
  2333. // libc_allocator_with_alloc.
  2334. // -----------------------------------------------------------------------
  2335. void _group_erase_aux(Alloc &alloc, size_type offset, spp_::true_type)
  2336. {
  2337. // static int x=0; if (++x < 10) printf("Y\n"); // check we are getting here
  2338. uint32_t num_items = _num_items();
  2339. uint32_t num_alloc = _sizing(num_items);
  2340. if (num_items == 1)
  2341. {
  2342. assert(offset == 0);
  2343. _free_group(alloc, num_alloc);
  2344. _set_num_alloc(0);
  2345. return;
  2346. }
  2347. _group[offset].~mutable_value_type();
  2348. for (size_type i = offset; i < num_items - 1; ++i)
  2349. memcpy(_group + i, _group + i + 1, sizeof(*_group));
  2350. if (_sizing(num_items - 1) != num_alloc)
  2351. {
  2352. num_alloc = _sizing(num_items - 1);
  2353. assert(num_alloc); // because we have at least 1 item left
  2354. _set_num_alloc(num_alloc);
  2355. _group = alloc.reallocate(_group, num_alloc);
  2356. }
  2357. }
  2358. // Shrink the array, without any special assumptions about value_type and
  2359. // allocator_type.
  2360. // --------------------------------------------------------------------------
  2361. void _group_erase_aux(Alloc &alloc, size_type offset, spp_::false_type)
  2362. {
  2363. uint32_t num_items = _num_items();
  2364. uint32_t num_alloc = _sizing(num_items);
  2365. if (_sizing(num_items - 1) != num_alloc)
  2366. {
  2367. mutable_pointer p = 0;
  2368. if (num_items > 1)
  2369. {
  2370. p = _allocate_group(alloc, num_items - 1);
  2371. if (offset)
  2372. std::uninitialized_copy(MK_MOVE_IT(_group),
  2373. MK_MOVE_IT(_group + offset),
  2374. p);
  2375. if (static_cast<uint32_t>(offset + 1) < num_items)
  2376. std::uninitialized_copy(MK_MOVE_IT(_group + offset + 1),
  2377. MK_MOVE_IT(_group + num_items),
  2378. p + offset);
  2379. }
  2380. else
  2381. {
  2382. assert(offset == 0);
  2383. _set_num_alloc(0);
  2384. }
  2385. _free_group(alloc, num_alloc);
  2386. _group = p;
  2387. }
  2388. else
  2389. {
  2390. std::rotate(_group + offset, _group + offset + 1, _group + num_items);
  2391. _group[num_items - 1].~mutable_value_type();
  2392. }
  2393. }
  2394. void _group_erase(Alloc &alloc, size_type offset)
  2395. {
  2396. _group_erase_aux(alloc, offset, realloc_and_memmove_ok());
  2397. }
  2398. public:
  2399. template <class twod_iter>
  2400. bool erase_ne(Alloc &alloc, twod_iter &it)
  2401. {
  2402. assert(_group && it.col_current != ne_end());
  2403. size_type offset = (size_type)(it.col_current - ne_begin());
  2404. size_type pos = offset_to_pos(offset);
  2405. if (_num_items() <= 1)
  2406. {
  2407. clear(alloc, false);
  2408. it.col_current = 0;
  2409. }
  2410. else
  2411. {
  2412. _group_erase(alloc, offset);
  2413. _decr_num_items();
  2414. _bmclear(pos);
  2415. // in case _group_erase reallocated the buffer
  2416. it.col_current = reinterpret_cast<pointer>(_group) + offset;
  2417. }
  2418. _bme_set(pos); // remember that this position has been erased
  2419. it.advance_past_end();
  2420. return true;
  2421. }
  2422. // This takes the specified elements out of the group. This is
  2423. // "undefining", rather than "clearing".
  2424. // TODO(austern): Make this exception safe: handle exceptions from
  2425. // value_type's copy constructor.
  2426. // ---------------------------------------------------------------
  2427. void erase(Alloc &alloc, size_type i)
  2428. {
  2429. if (_bmtest(i))
  2430. {
  2431. // trivial to erase empty bucket
  2432. if (_num_items() == 1)
  2433. clear(alloc, false);
  2434. else
  2435. {
  2436. _group_erase(alloc, pos_to_offset(i));
  2437. _decr_num_items();
  2438. _bmclear(i);
  2439. }
  2440. _bme_set(i); // remember that this position has been erased
  2441. }
  2442. }
  2443. // I/O
  2444. // We support reading and writing groups to disk. We don't store
  2445. // the actual array contents (which we don't know how to store),
  2446. // just the bitmap and size. Meant to be used with table I/O.
  2447. // --------------------------------------------------------------
  2448. template <typename OUTPUT> bool write_metadata(OUTPUT *fp) const
  2449. {
  2450. // warning: we write 4 or 8 bytes for the bitmap, instead of 6 in the
  2451. // original google sparsehash
  2452. // ------------------------------------------------------------------
  2453. if (!sparsehash_internal::write_data(fp, &_bitmap, sizeof(_bitmap)))
  2454. return false;
  2455. return true;
  2456. }
  2457. // Reading destroys the old group contents! Returns true if all was ok.
  2458. template <typename INPUT> bool read_metadata(Alloc &alloc, INPUT *fp)
  2459. {
  2460. clear(alloc, true);
  2461. if (!sparsehash_internal::read_data(fp, &_bitmap, sizeof(_bitmap)))
  2462. return false;
  2463. // We'll allocate the space, but we won't fill it: it will be
  2464. // left as uninitialized raw memory.
  2465. uint32_t num_items = spp_popcount(_bitmap); // yes, _num_buckets not set
  2466. _set_num_items(num_items);
  2467. _group = num_items ? _allocate_group(alloc, num_items/* , true */) : 0;
  2468. return true;
  2469. }
  2470. // Again, only meaningful if value_type is a POD.
  2471. template <typename INPUT> bool read_nopointer_data(INPUT *fp)
  2472. {
  2473. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  2474. if (!sparsehash_internal::read_data(fp, &(*it), sizeof(*it)))
  2475. return false;
  2476. return true;
  2477. }
  2478. // If your keys and values are simple enough, we can write them
  2479. // to disk for you. "simple enough" means POD and no pointers.
  2480. // However, we don't try to normalize endianness.
  2481. // ------------------------------------------------------------
  2482. template <typename OUTPUT> bool write_nopointer_data(OUTPUT *fp) const
  2483. {
  2484. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  2485. if (!sparsehash_internal::write_data(fp, &(*it), sizeof(*it)))
  2486. return false;
  2487. return true;
  2488. }
  2489. // Comparisons. We only need to define == and < -- we get
  2490. // != > <= >= via relops.h (which we happily included above).
  2491. // Note the comparisons are pretty arbitrary: we compare
  2492. // values of the first index that isn't equal (using default
  2493. // value for empty buckets).
  2494. // ---------------------------------------------------------
  2495. bool operator==(const sparsegroup& x) const
  2496. {
  2497. return (_bitmap == x._bitmap &&
  2498. _bm_erased == x._bm_erased &&
  2499. std::equal(_group, _group + _num_items(), x._group));
  2500. }
  2501. bool operator<(const sparsegroup& x) const
  2502. {
  2503. // also from <algorithm>
  2504. return std::lexicographical_compare(_group, _group + _num_items(),
  2505. x._group, x._group + x._num_items());
  2506. }
  2507. bool operator!=(const sparsegroup& x) const { return !(*this == x); }
  2508. bool operator<=(const sparsegroup& x) const { return !(x < *this); }
  2509. bool operator> (const sparsegroup& x) const { return x < *this; }
  2510. bool operator>=(const sparsegroup& x) const { return !(*this < x); }
  2511. void mark() { _group = (mutable_value_type *)static_cast<uintptr_t>(-1); }
  2512. bool is_marked() const { return _group == (mutable_value_type *)static_cast<uintptr_t>(-1); }
  2513. private:
  2514. // ---------------------------------------------------------------------------
  2515. template <class A>
  2516. class alloc_impl : public A
  2517. {
  2518. public:
  2519. typedef typename A::pointer pointer;
  2520. typedef typename A::size_type size_type;
  2521. // Convert a normal allocator to one that has realloc_or_die()
  2522. explicit alloc_impl(const A& a) : A(a) { }
  2523. // realloc_or_die should only be used when using the default
  2524. // allocator (libc_allocator_with_realloc).
  2525. pointer realloc_or_die(pointer /*ptr*/, size_type /*n*/)
  2526. {
  2527. fprintf(stderr, "realloc_or_die is only supported for "
  2528. "libc_allocator_with_realloc\n");
  2529. exit(1);
  2530. return NULL;
  2531. }
  2532. };
  2533. // A template specialization of alloc_impl for
  2534. // libc_allocator_with_realloc that can handle realloc_or_die.
  2535. // -----------------------------------------------------------
  2536. template <class A>
  2537. class alloc_impl<libc_allocator_with_realloc<A> >
  2538. : public libc_allocator_with_realloc<A>
  2539. {
  2540. public:
  2541. typedef typename libc_allocator_with_realloc<A>::pointer pointer;
  2542. typedef typename libc_allocator_with_realloc<A>::size_type size_type;
  2543. explicit alloc_impl(const libc_allocator_with_realloc<A>& a)
  2544. : libc_allocator_with_realloc<A>(a)
  2545. { }
  2546. pointer realloc_or_die(pointer ptr, size_type n)
  2547. {
  2548. pointer retval = this->reallocate(ptr, n);
  2549. if (retval == NULL) {
  2550. fprintf(stderr, "sparsehash: FATAL ERROR: failed to reallocate "
  2551. "%lu elements for ptr %p", static_cast<unsigned long>(n), ptr);
  2552. exit(1);
  2553. }
  2554. return retval;
  2555. }
  2556. };
  2557. #ifdef SPP_STORE_NUM_ITEMS
  2558. uint32_t _num_items() const { return (uint32_t)_num_buckets; }
  2559. void _set_num_items(uint32_t val) { _num_buckets = static_cast<size_type>(val); }
  2560. void _incr_num_items() { ++_num_buckets; }
  2561. void _decr_num_items() { --_num_buckets; }
  2562. uint32_t _num_alloc() const { return (uint32_t)_num_allocated; }
  2563. void _set_num_alloc(uint32_t val) { _num_allocated = static_cast<size_type>(val); }
  2564. #else
  2565. uint32_t _num_items() const { return spp_popcount(_bitmap); }
  2566. void _set_num_items(uint32_t ) { }
  2567. void _incr_num_items() { }
  2568. void _decr_num_items() { }
  2569. uint32_t _num_alloc() const { return _sizing(_num_items()); }
  2570. void _set_num_alloc(uint32_t val) { }
  2571. #endif
  2572. // The actual data
  2573. // ---------------
  2574. mutable_value_type * _group; // (small) array of T's
  2575. group_bm_type _bitmap;
  2576. group_bm_type _bm_erased; // ones where items have been erased
  2577. #ifdef SPP_STORE_NUM_ITEMS
  2578. size_type _num_buckets;
  2579. size_type _num_allocated;
  2580. #endif
  2581. };
  2582. // ---------------------------------------------------------------------------
  2583. // We need a global swap as well
  2584. // ---------------------------------------------------------------------------
  2585. template <class T, class Alloc>
  2586. inline void swap(sparsegroup<T,Alloc> &x, sparsegroup<T,Alloc> &y)
  2587. {
  2588. x.swap(y);
  2589. }
  2590. // ---------------------------------------------------------------------------
  2591. // ---------------------------------------------------------------------------
  2592. template <class T, class Alloc = libc_allocator_with_realloc<T> >
  2593. class sparsetable
  2594. {
  2595. private:
  2596. typedef typename Alloc::template rebind<T>::other value_alloc_type;
  2597. typedef typename Alloc::template rebind<
  2598. sparsegroup<T, value_alloc_type> >::other group_alloc_type;
  2599. typedef typename group_alloc_type::size_type group_size_type;
  2600. typedef T mutable_value_type;
  2601. typedef mutable_value_type* mutable_pointer;
  2602. typedef const mutable_value_type* const_mutable_pointer;
  2603. public:
  2604. // Basic types
  2605. // -----------
  2606. typedef typename spp::cvt<T>::type value_type;
  2607. typedef Alloc allocator_type;
  2608. typedef typename value_alloc_type::size_type size_type;
  2609. typedef typename value_alloc_type::difference_type difference_type;
  2610. typedef value_type& reference;
  2611. typedef const value_type& const_reference;
  2612. typedef value_type* pointer;
  2613. typedef const value_type* const_pointer;
  2614. typedef sparsegroup<T, value_alloc_type> group_type;
  2615. typedef group_type& GroupsReference;
  2616. typedef const group_type& GroupsConstReference;
  2617. typedef typename group_type::ne_iterator ColIterator;
  2618. typedef typename group_type::const_ne_iterator ColConstIterator;
  2619. typedef table_iterator<sparsetable<T, Alloc> > iterator; // defined with index
  2620. typedef const_table_iterator<sparsetable<T, Alloc> > const_iterator; // defined with index
  2621. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  2622. typedef std::reverse_iterator<iterator> reverse_iterator;
  2623. // These are our special iterators, that go over non-empty buckets in a
  2624. // table. These aren't const only because you can change non-empty bcks.
  2625. // ----------------------------------------------------------------------
  2626. typedef Two_d_iterator<T,
  2627. group_type *,
  2628. ColIterator,
  2629. std::bidirectional_iterator_tag> ne_iterator;
  2630. typedef Two_d_iterator<const T,
  2631. const group_type *,
  2632. ColConstIterator,
  2633. std::bidirectional_iterator_tag> const_ne_iterator;
  2634. // Another special iterator: it frees memory as it iterates (used to resize).
  2635. // Obviously, you can only iterate over it once, which is why it's an input iterator
  2636. // ---------------------------------------------------------------------------------
  2637. typedef Two_d_destructive_iterator<T,
  2638. group_type *,
  2639. ColIterator,
  2640. std::input_iterator_tag,
  2641. allocator_type> destructive_iterator;
  2642. typedef std::reverse_iterator<ne_iterator> reverse_ne_iterator;
  2643. typedef std::reverse_iterator<const_ne_iterator> const_reverse_ne_iterator;
  2644. // Iterator functions
  2645. // ------------------
  2646. iterator begin() { return iterator(this, 0); }
  2647. const_iterator begin() const { return const_iterator(this, 0); }
  2648. const_iterator cbegin() const { return const_iterator(this, 0); }
  2649. iterator end() { return iterator(this, size()); }
  2650. const_iterator end() const { return const_iterator(this, size()); }
  2651. const_iterator cend() const { return const_iterator(this, size()); }
  2652. reverse_iterator rbegin() { return reverse_iterator(end()); }
  2653. const_reverse_iterator rbegin() const { return const_reverse_iterator(cend()); }
  2654. const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
  2655. reverse_iterator rend() { return reverse_iterator(begin()); }
  2656. const_reverse_iterator rend() const { return const_reverse_iterator(cbegin()); }
  2657. const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
  2658. // Versions for our special non-empty iterator
  2659. // ------------------------------------------
  2660. ne_iterator ne_begin() { return ne_iterator (_first_group); }
  2661. const_ne_iterator ne_begin() const { return const_ne_iterator(_first_group); }
  2662. const_ne_iterator ne_cbegin() const { return const_ne_iterator(_first_group); }
  2663. ne_iterator ne_end() { return ne_iterator (_last_group); }
  2664. const_ne_iterator ne_end() const { return const_ne_iterator(_last_group); }
  2665. const_ne_iterator ne_cend() const { return const_ne_iterator(_last_group); }
  2666. reverse_ne_iterator ne_rbegin() { return reverse_ne_iterator(ne_end()); }
  2667. const_reverse_ne_iterator ne_rbegin() const { return const_reverse_ne_iterator(ne_end()); }
  2668. const_reverse_ne_iterator ne_crbegin() const { return const_reverse_ne_iterator(ne_end()); }
  2669. reverse_ne_iterator ne_rend() { return reverse_ne_iterator(ne_begin()); }
  2670. const_reverse_ne_iterator ne_rend() const { return const_reverse_ne_iterator(ne_begin()); }
  2671. const_reverse_ne_iterator ne_crend() const { return const_reverse_ne_iterator(ne_begin()); }
  2672. destructive_iterator destructive_begin()
  2673. {
  2674. return destructive_iterator(_alloc, _first_group);
  2675. }
  2676. destructive_iterator destructive_end()
  2677. {
  2678. return destructive_iterator(_alloc, _last_group);
  2679. }
  2680. // How to deal with the proper group
  2681. static group_size_type num_groups(group_size_type num)
  2682. {
  2683. // how many to hold num buckets
  2684. return num == 0 ? (group_size_type)0 :
  2685. (group_size_type)(((num-1) / SPP_GROUP_SIZE) + 1);
  2686. }
  2687. typename group_type::size_type pos_in_group(size_type i) const
  2688. {
  2689. return static_cast<typename group_type::size_type>(i & SPP_MASK_);
  2690. }
  2691. size_type group_num(size_type i) const
  2692. {
  2693. return (size_type)(i >> SPP_SHIFT_);
  2694. }
  2695. GroupsReference which_group(size_type i)
  2696. {
  2697. return _first_group[group_num(i)];
  2698. }
  2699. GroupsConstReference which_group(size_type i) const
  2700. {
  2701. return _first_group[group_num(i)];
  2702. }
  2703. void _alloc_group_array(group_size_type sz, group_type *&first, group_type *&last)
  2704. {
  2705. if (sz)
  2706. {
  2707. first = _group_alloc.allocate((size_type)(sz + 1)); // + 1 for end marker
  2708. first[sz].mark(); // for the ne_iterator
  2709. last = first + sz;
  2710. }
  2711. }
  2712. void _free_group_array(group_type *&first, group_type *&last)
  2713. {
  2714. if (first)
  2715. {
  2716. _group_alloc.deallocate(first, (group_size_type)(last - first + 1)); // + 1 for end marker
  2717. first = last = 0;
  2718. }
  2719. }
  2720. void _allocate_groups(size_type sz)
  2721. {
  2722. if (sz)
  2723. {
  2724. _alloc_group_array(sz, _first_group, _last_group);
  2725. std::uninitialized_fill(_first_group, _last_group, group_type());
  2726. }
  2727. }
  2728. void _free_groups()
  2729. {
  2730. if (_first_group)
  2731. {
  2732. for (group_type *g = _first_group; g != _last_group; ++g)
  2733. g->destruct(_alloc);
  2734. _free_group_array(_first_group, _last_group);
  2735. }
  2736. }
  2737. void _cleanup()
  2738. {
  2739. _free_groups(); // sets _first_group = _last_group = 0
  2740. _table_size = 0;
  2741. _num_buckets = 0;
  2742. }
  2743. void _init()
  2744. {
  2745. _first_group = 0;
  2746. _last_group = 0;
  2747. _table_size = 0;
  2748. _num_buckets = 0;
  2749. }
  2750. void _copy(const sparsetable &o)
  2751. {
  2752. _table_size = o._table_size;
  2753. _num_buckets = o._num_buckets;
  2754. _alloc = o._alloc; // todo - copy or move allocator according to...
  2755. _group_alloc = o._group_alloc; // http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map
  2756. group_size_type sz = (group_size_type)(o._last_group - o._first_group);
  2757. if (sz)
  2758. {
  2759. _alloc_group_array(sz, _first_group, _last_group);
  2760. for (group_size_type i=0; i<sz; ++i)
  2761. new (_first_group + i) group_type(o._first_group[i], _alloc);
  2762. }
  2763. }
  2764. public:
  2765. // Constructors -- default, normal (when you specify size), and copy
  2766. explicit sparsetable(size_type sz = 0, const Alloc &alloc = Alloc()) :
  2767. _first_group(0),
  2768. _last_group(0),
  2769. _table_size(sz),
  2770. _num_buckets(0),
  2771. _alloc(alloc) // todo - copy or move allocator according to
  2772. // http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map
  2773. {
  2774. _allocate_groups(num_groups(sz));
  2775. }
  2776. ~sparsetable()
  2777. {
  2778. _free_groups();
  2779. }
  2780. sparsetable(const sparsetable &o)
  2781. {
  2782. _init();
  2783. _copy(o);
  2784. }
  2785. sparsetable& operator=(const sparsetable &o)
  2786. {
  2787. _cleanup();
  2788. _copy(o);
  2789. return *this;
  2790. }
  2791. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  2792. sparsetable(sparsetable&& o)
  2793. {
  2794. _init();
  2795. this->swap(o);
  2796. }
  2797. sparsetable(sparsetable&& o, const Alloc &alloc)
  2798. {
  2799. _init();
  2800. this->swap(o);
  2801. _alloc = alloc; // [gp todo] is this correct?
  2802. }
  2803. sparsetable& operator=(sparsetable&& o)
  2804. {
  2805. _cleanup();
  2806. this->swap(o);
  2807. return *this;
  2808. }
  2809. #endif
  2810. // Many STL algorithms use swap instead of copy constructors
  2811. void swap(sparsetable& o)
  2812. {
  2813. using std::swap;
  2814. swap(_first_group, o._first_group);
  2815. swap(_last_group, o._last_group);
  2816. swap(_table_size, o._table_size);
  2817. swap(_num_buckets, o._num_buckets);
  2818. if (_alloc != o._alloc)
  2819. swap(_alloc, o._alloc);
  2820. if (_group_alloc != o._group_alloc)
  2821. swap(_group_alloc, o._group_alloc);
  2822. }
  2823. // It's always nice to be able to clear a table without deallocating it
  2824. void clear()
  2825. {
  2826. _free_groups();
  2827. _num_buckets = 0;
  2828. _table_size = 0;
  2829. }
  2830. inline allocator_type get_allocator() const
  2831. {
  2832. return _alloc;
  2833. }
  2834. // Functions that tell you about size.
  2835. // NOTE: empty() is non-intuitive! It does not tell you the number
  2836. // of not-empty buckets (use num_nonempty() for that). Instead
  2837. // it says whether you've allocated any buckets or not.
  2838. // ----------------------------------------------------------------
  2839. size_type size() const { return _table_size; }
  2840. size_type max_size() const { return _alloc.max_size(); }
  2841. bool empty() const { return _table_size == 0; }
  2842. size_type num_nonempty() const { return _num_buckets; }
  2843. // OK, we'll let you resize one of these puppies
  2844. void resize(size_type new_size)
  2845. {
  2846. group_size_type sz = num_groups(new_size);
  2847. group_size_type old_sz = (group_size_type)(_last_group - _first_group);
  2848. if (sz != old_sz)
  2849. {
  2850. // resize group array
  2851. // ------------------
  2852. group_type *first = 0, *last = 0;
  2853. if (sz)
  2854. {
  2855. _alloc_group_array(sz, first, last);
  2856. memcpy(first, _first_group, sizeof(*first) * (std::min)(sz, old_sz));
  2857. }
  2858. if (sz < old_sz)
  2859. {
  2860. for (group_type *g = _first_group + sz; g != _last_group; ++g)
  2861. g->destruct(_alloc);
  2862. }
  2863. else
  2864. std::uninitialized_fill(first + old_sz, last, group_type());
  2865. _free_group_array(_first_group, _last_group);
  2866. _first_group = first;
  2867. _last_group = last;
  2868. }
  2869. #if 0
  2870. // used only in test program
  2871. // todo: fix if sparsetable to be used directly
  2872. // --------------------------------------------
  2873. if (new_size < _table_size)
  2874. {
  2875. // lower num_buckets, clear last group
  2876. if (pos_in_group(new_size) > 0) // need to clear inside last group
  2877. groups.back().erase(_alloc, groups.back().begin() + pos_in_group(new_size),
  2878. groups.back().end());
  2879. _num_buckets = 0; // refigure # of used buckets
  2880. for (const group_type *group = _first_group; group != _last_group; ++group)
  2881. _num_buckets += group->num_nonempty();
  2882. }
  2883. #endif
  2884. _table_size = new_size;
  2885. }
  2886. // We let you see if a bucket is non-empty without retrieving it
  2887. // -------------------------------------------------------------
  2888. bool test(size_type i) const
  2889. {
  2890. // assert(i < _table_size);
  2891. return which_group(i).test(pos_in_group(i));
  2892. }
  2893. // also tests for erased values
  2894. // ----------------------------
  2895. bool test_strict(size_type i) const
  2896. {
  2897. // assert(i < _table_size);
  2898. return which_group(i).test_strict(pos_in_group(i));
  2899. }
  2900. friend struct GrpPos;
  2901. struct GrpPos
  2902. {
  2903. typedef typename sparsetable::ne_iterator ne_iter;
  2904. GrpPos(const sparsetable &table, size_type i) :
  2905. grp(table.which_group(i)), pos(table.pos_in_group(i)) {}
  2906. bool test_strict() const { return grp.test_strict(pos); }
  2907. bool test() const { return grp.test(pos); }
  2908. typename sparsetable::reference unsafe_get() const { return grp.unsafe_get(pos); }
  2909. ne_iter get_iter(typename sparsetable::reference ref)
  2910. {
  2911. return ne_iter((group_type *)&grp, &ref);
  2912. }
  2913. void erase(sparsetable &table) // item *must* be present
  2914. {
  2915. assert(table._num_buckets);
  2916. ((group_type &)grp).erase(table._alloc, pos);
  2917. --table._num_buckets;
  2918. }
  2919. private:
  2920. GrpPos* operator=(const GrpPos&);
  2921. const group_type &grp;
  2922. typename group_type::size_type pos;
  2923. };
  2924. bool test(iterator pos) const
  2925. {
  2926. return which_group(pos.pos).test(pos_in_group(pos.pos));
  2927. }
  2928. bool test(const_iterator pos) const
  2929. {
  2930. return which_group(pos.pos).test(pos_in_group(pos.pos));
  2931. }
  2932. // TODO(csilvers): make protected + friend
  2933. // This is used by sparse_hashtable to get an element from the table
  2934. // when we know it exists (because the caller has called test(i)).
  2935. // -----------------------------------------------------------------
  2936. reference unsafe_get(size_type i) const
  2937. {
  2938. assert(i < _table_size);
  2939. // assert(test(i));
  2940. return which_group(i).unsafe_get(pos_in_group(i));
  2941. }
  2942. // Needed for hashtables, gets as a ne_iterator. Crashes for empty bcks
  2943. const_ne_iterator get_iter(size_type i) const
  2944. {
  2945. //assert(test(i)); // how can a ne_iterator point to an empty bucket?
  2946. size_type grp_idx = group_num(i);
  2947. return const_ne_iterator(_first_group + grp_idx,
  2948. (_first_group[grp_idx].ne_begin() +
  2949. _first_group[grp_idx].pos_to_offset(pos_in_group(i))));
  2950. }
  2951. const_ne_iterator get_iter(size_type i, ColIterator col_it) const
  2952. {
  2953. return const_ne_iterator(_first_group + group_num(i), col_it);
  2954. }
  2955. // For nonempty we can return a non-const version
  2956. ne_iterator get_iter(size_type i)
  2957. {
  2958. //assert(test(i)); // how can a nonempty_iterator point to an empty bucket?
  2959. size_type grp_idx = group_num(i);
  2960. return ne_iterator(_first_group + grp_idx,
  2961. (_first_group[grp_idx].ne_begin() +
  2962. _first_group[grp_idx].pos_to_offset(pos_in_group(i))));
  2963. }
  2964. ne_iterator get_iter(size_type i, ColIterator col_it)
  2965. {
  2966. return ne_iterator(_first_group + group_num(i), col_it);
  2967. }
  2968. // And the reverse transformation.
  2969. size_type get_pos(const const_ne_iterator& it) const
  2970. {
  2971. difference_type current_row = it.row_current - _first_group;
  2972. difference_type current_col = (it.col_current - _first_group[current_row].ne_begin());
  2973. return ((current_row * SPP_GROUP_SIZE) +
  2974. _first_group[current_row].offset_to_pos(current_col));
  2975. }
  2976. // Val can be reference or const_reference
  2977. // ---------------------------------------
  2978. template <class Val>
  2979. reference set(size_type i, Val &val)
  2980. {
  2981. assert(i < _table_size);
  2982. group_type &group = which_group(i);
  2983. typename group_type::size_type old_numbuckets = group.num_nonempty();
  2984. pointer p(group.set(_alloc, pos_in_group(i), val));
  2985. _num_buckets += group.num_nonempty() - old_numbuckets;
  2986. return *p;
  2987. }
  2988. // used in _move_from (where we can move the old value instead of copying it
  2989. void move(size_type i, reference val)
  2990. {
  2991. assert(i < _table_size);
  2992. which_group(i).set(_alloc, pos_in_group(i), val);
  2993. ++_num_buckets;
  2994. }
  2995. // This takes the specified elements out of the table.
  2996. // --------------------------------------------------
  2997. void erase(size_type i)
  2998. {
  2999. assert(i < _table_size);
  3000. GroupsReference grp(which_group(i));
  3001. typename group_type::size_type old_numbuckets = grp.num_nonempty();
  3002. grp.erase(_alloc, pos_in_group(i));
  3003. _num_buckets += grp.num_nonempty() - old_numbuckets;
  3004. }
  3005. void erase(iterator pos)
  3006. {
  3007. erase(pos.pos);
  3008. }
  3009. void erase(iterator start_it, iterator end_it)
  3010. {
  3011. // This could be more efficient, but then we'd need to figure
  3012. // out if we spanned groups or not. Doesn't seem worth it.
  3013. for (; start_it != end_it; ++start_it)
  3014. erase(start_it);
  3015. }
  3016. const_ne_iterator erase(const_ne_iterator it)
  3017. {
  3018. ne_iterator res(it);
  3019. if (res.row_current->erase_ne(_alloc, res))
  3020. _num_buckets--;
  3021. return res;
  3022. }
  3023. const_ne_iterator erase(const_ne_iterator f, const_ne_iterator l)
  3024. {
  3025. size_t diff = l - f;
  3026. while (diff--)
  3027. f = erase(f);
  3028. return f;
  3029. }
  3030. // We support reading and writing tables to disk. We don't store
  3031. // the actual array contents (which we don't know how to store),
  3032. // just the groups and sizes. Returns true if all went ok.
  3033. private:
  3034. // Every time the disk format changes, this should probably change too
  3035. typedef unsigned long MagicNumberType;
  3036. static const MagicNumberType MAGIC_NUMBER = 0x24687531;
  3037. // Old versions of this code write all data in 32 bits. We need to
  3038. // support these files as well as having support for 64-bit systems.
  3039. // So we use the following encoding scheme: for values < 2^32-1, we
  3040. // store in 4 bytes in big-endian order. For values > 2^32, we
  3041. // store 0xFFFFFFF followed by 8 bytes in big-endian order. This
  3042. // causes us to mis-read old-version code that stores exactly
  3043. // 0xFFFFFFF, but I don't think that is likely to have happened for
  3044. // these particular values.
  3045. template <typename OUTPUT, typename IntType>
  3046. static bool write_32_or_64(OUTPUT* fp, IntType value)
  3047. {
  3048. if (value < 0xFFFFFFFFULL) { // fits in 4 bytes
  3049. if (!sparsehash_internal::write_bigendian_number(fp, value, 4))
  3050. return false;
  3051. }
  3052. else
  3053. {
  3054. if (!sparsehash_internal::write_bigendian_number(fp, 0xFFFFFFFFUL, 4))
  3055. return false;
  3056. if (!sparsehash_internal::write_bigendian_number(fp, value, 8))
  3057. return false;
  3058. }
  3059. return true;
  3060. }
  3061. template <typename INPUT, typename IntType>
  3062. static bool read_32_or_64(INPUT* fp, IntType *value)
  3063. { // reads into value
  3064. MagicNumberType first4 = 0; // a convenient 32-bit unsigned type
  3065. if (!sparsehash_internal::read_bigendian_number(fp, &first4, 4))
  3066. return false;
  3067. if (first4 < 0xFFFFFFFFULL)
  3068. {
  3069. *value = first4;
  3070. }
  3071. else
  3072. {
  3073. if (!sparsehash_internal::read_bigendian_number(fp, value, 8))
  3074. return false;
  3075. }
  3076. return true;
  3077. }
  3078. public:
  3079. // read/write_metadata() and read_write/nopointer_data() are DEPRECATED.
  3080. // Use serialize() and unserialize(), below, for new code.
  3081. template <typename OUTPUT>
  3082. bool write_metadata(OUTPUT *fp) const
  3083. {
  3084. if (!write_32_or_64(fp, MAGIC_NUMBER)) return false;
  3085. if (!write_32_or_64(fp, _table_size)) return false;
  3086. if (!write_32_or_64(fp, _num_buckets)) return false;
  3087. for (const group_type *group = _first_group; group != _last_group; ++group)
  3088. if (group->write_metadata(fp) == false)
  3089. return false;
  3090. return true;
  3091. }
  3092. // Reading destroys the old table contents! Returns true if read ok.
  3093. template <typename INPUT>
  3094. bool read_metadata(INPUT *fp)
  3095. {
  3096. size_type magic_read = 0;
  3097. if (!read_32_or_64(fp, &magic_read)) return false;
  3098. if (magic_read != MAGIC_NUMBER)
  3099. {
  3100. clear(); // just to be consistent
  3101. return false;
  3102. }
  3103. if (!read_32_or_64(fp, &_table_size)) return false;
  3104. if (!read_32_or_64(fp, &_num_buckets)) return false;
  3105. resize(_table_size); // so the vector's sized ok
  3106. for (group_type *group = _first_group; group != _last_group; ++group)
  3107. if (group->read_metadata(_alloc, fp) == false)
  3108. return false;
  3109. return true;
  3110. }
  3111. // This code is identical to that for SparseGroup
  3112. // If your keys and values are simple enough, we can write them
  3113. // to disk for you. "simple enough" means no pointers.
  3114. // However, we don't try to normalize endianness
  3115. bool write_nopointer_data(FILE *fp) const
  3116. {
  3117. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3118. if (!fwrite(&*it, sizeof(*it), 1, fp))
  3119. return false;
  3120. return true;
  3121. }
  3122. // When reading, we have to override the potential const-ness of *it
  3123. bool read_nopointer_data(FILE *fp)
  3124. {
  3125. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3126. if (!fread(reinterpret_cast<void*>(&(*it)), sizeof(*it), 1, fp))
  3127. return false;
  3128. return true;
  3129. }
  3130. // INPUT and OUTPUT must be either a FILE, *or* a C++ stream
  3131. // (istream, ostream, etc) *or* a class providing
  3132. // Read(void*, size_t) and Write(const void*, size_t)
  3133. // (respectively), which writes a buffer into a stream
  3134. // (which the INPUT/OUTPUT instance presumably owns).
  3135. typedef sparsehash_internal::pod_serializer<value_type> NopointerSerializer;
  3136. // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&)
  3137. template <typename ValueSerializer, typename OUTPUT>
  3138. bool serialize(ValueSerializer serializer, OUTPUT *fp)
  3139. {
  3140. if (!write_metadata(fp))
  3141. return false;
  3142. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3143. if (!serializer(fp, *it))
  3144. return false;
  3145. return true;
  3146. }
  3147. // ValueSerializer: a functor. operator()(INPUT*, value_type*)
  3148. template <typename ValueSerializer, typename INPUT>
  3149. bool unserialize(ValueSerializer serializer, INPUT *fp)
  3150. {
  3151. clear();
  3152. if (!read_metadata(fp))
  3153. return false;
  3154. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3155. if (!serializer(fp, &*it))
  3156. return false;
  3157. return true;
  3158. }
  3159. // Comparisons. Note the comparisons are pretty arbitrary: we
  3160. // compare values of the first index that isn't equal (using default
  3161. // value for empty buckets).
  3162. bool operator==(const sparsetable& x) const
  3163. {
  3164. return (_table_size == x._table_size &&
  3165. _num_buckets == x._num_buckets &&
  3166. _first_group == x._first_group);
  3167. }
  3168. bool operator<(const sparsetable& x) const
  3169. {
  3170. return std::lexicographical_compare(begin(), end(), x.begin(), x.end());
  3171. }
  3172. bool operator!=(const sparsetable& x) const { return !(*this == x); }
  3173. bool operator<=(const sparsetable& x) const { return !(x < *this); }
  3174. bool operator>(const sparsetable& x) const { return x < *this; }
  3175. bool operator>=(const sparsetable& x) const { return !(*this < x); }
  3176. private:
  3177. // The actual data
  3178. // ---------------
  3179. group_type * _first_group;
  3180. group_type * _last_group;
  3181. size_type _table_size; // how many buckets they want
  3182. size_type _num_buckets; // number of non-empty buckets
  3183. group_alloc_type _group_alloc;
  3184. value_alloc_type _alloc;
  3185. };
  3186. // We need a global swap as well
  3187. // ---------------------------------------------------------------------------
  3188. template <class T, class Alloc>
  3189. inline void swap(sparsetable<T,Alloc> &x, sparsetable<T,Alloc> &y)
  3190. {
  3191. x.swap(y);
  3192. }
  3193. // ----------------------------------------------------------------------
  3194. // S P A R S E _ H A S H T A B L E
  3195. // ----------------------------------------------------------------------
  3196. // Hashtable class, used to implement the hashed associative containers
  3197. // hash_set and hash_map.
  3198. //
  3199. // Value: what is stored in the table (each bucket is a Value).
  3200. // Key: something in a 1-to-1 correspondence to a Value, that can be used
  3201. // to search for a Value in the table (find() takes a Key).
  3202. // HashFcn: Takes a Key and returns an integer, the more unique the better.
  3203. // ExtractKey: given a Value, returns the unique Key associated with it.
  3204. // Must inherit from unary_function, or at least have a
  3205. // result_type enum indicating the return type of operator().
  3206. // EqualKey: Given two Keys, says whether they are the same (that is,
  3207. // if they are both associated with the same Value).
  3208. // Alloc: STL allocator to use to allocate memory.
  3209. //
  3210. // ----------------------------------------------------------------------
  3211. // The probing method
  3212. // ------------------
  3213. // Linear probing
  3214. // #define JUMP_(key, num_probes) ( 1 )
  3215. // Quadratic probing
  3216. #define JUMP_(key, num_probes) ( num_probes )
  3217. // -------------------------------------------------------------------
  3218. // -------------------------------------------------------------------
  3219. template <class Value, class Key, class HashFcn,
  3220. class ExtractKey, class SetKey, class EqualKey, class Alloc>
  3221. class sparse_hashtable
  3222. {
  3223. private:
  3224. typedef Value mutable_value_type;
  3225. typedef typename Alloc::template rebind<Value>::other value_alloc_type;
  3226. public:
  3227. typedef Key key_type;
  3228. typedef typename spp::cvt<Value>::type value_type;
  3229. typedef HashFcn hasher; // user provided or spp_hash<Key>
  3230. typedef EqualKey key_equal;
  3231. typedef Alloc allocator_type;
  3232. typedef typename value_alloc_type::size_type size_type;
  3233. typedef typename value_alloc_type::difference_type difference_type;
  3234. typedef value_type& reference;
  3235. typedef const value_type& const_reference;
  3236. typedef value_type* pointer;
  3237. typedef const value_type* const_pointer;
  3238. // Table is the main storage class.
  3239. typedef sparsetable<mutable_value_type, value_alloc_type> Table;
  3240. typedef typename Table::ne_iterator ne_it;
  3241. typedef typename Table::const_ne_iterator cne_it;
  3242. typedef typename Table::destructive_iterator dest_it;
  3243. typedef typename Table::ColIterator ColIterator;
  3244. typedef ne_it iterator;
  3245. typedef cne_it const_iterator;
  3246. typedef dest_it destructive_iterator;
  3247. // These come from tr1. For us they're the same as regular iterators.
  3248. // -------------------------------------------------------------------
  3249. typedef iterator local_iterator;
  3250. typedef const_iterator const_local_iterator;
  3251. // How full we let the table get before we resize
  3252. // ----------------------------------------------
  3253. static const int HT_OCCUPANCY_PCT; // = 80 (out of 100);
  3254. // How empty we let the table get before we resize lower, by default.
  3255. // (0.0 means never resize lower.)
  3256. // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing
  3257. // ------------------------------------------------------------------
  3258. static const int HT_EMPTY_PCT; // = 0.4 * HT_OCCUPANCY_PCT;
  3259. // Minimum size we're willing to let hashtables be.
  3260. // Must be a power of two, and at least 4.
  3261. // Note, however, that for a given hashtable, the initial size is a
  3262. // function of the first constructor arg, and may be >HT_MIN_BUCKETS.
  3263. // ------------------------------------------------------------------
  3264. static const size_type HT_MIN_BUCKETS = 4;
  3265. // By default, if you don't specify a hashtable size at
  3266. // construction-time, we use this size. Must be a power of two, and
  3267. // at least HT_MIN_BUCKETS.
  3268. // -----------------------------------------------------------------
  3269. static const size_type HT_DEFAULT_STARTING_BUCKETS = 32;
  3270. // iterators
  3271. // ---------
  3272. iterator begin() { return _mk_iterator(table.ne_begin()); }
  3273. iterator end() { return _mk_iterator(table.ne_end()); }
  3274. const_iterator begin() const { return _mk_const_iterator(table.ne_cbegin()); }
  3275. const_iterator end() const { return _mk_const_iterator(table.ne_cend()); }
  3276. const_iterator cbegin() const { return _mk_const_iterator(table.ne_cbegin()); }
  3277. const_iterator cend() const { return _mk_const_iterator(table.ne_cend()); }
  3278. // These come from tr1 unordered_map. They iterate over 'bucket' n.
  3279. // For sparsehashtable, we could consider each 'group' to be a bucket,
  3280. // I guess, but I don't really see the point. We'll just consider
  3281. // bucket n to be the n-th element of the sparsetable, if it's occupied,
  3282. // or some empty element, otherwise.
  3283. // ---------------------------------------------------------------------
  3284. local_iterator begin(size_type i)
  3285. {
  3286. return _mk_iterator(table.test(i) ? table.get_iter(i) : table.ne_end());
  3287. }
  3288. local_iterator end(size_type i)
  3289. {
  3290. local_iterator it = begin(i);
  3291. if (table.test(i))
  3292. ++it;
  3293. return _mk_iterator(it);
  3294. }
  3295. const_local_iterator begin(size_type i) const
  3296. {
  3297. return _mk_const_iterator(table.test(i) ? table.get_iter(i) : table.ne_cend());
  3298. }
  3299. const_local_iterator end(size_type i) const
  3300. {
  3301. const_local_iterator it = begin(i);
  3302. if (table.test(i))
  3303. ++it;
  3304. return _mk_const_iterator(it);
  3305. }
  3306. const_local_iterator cbegin(size_type i) const { return begin(i); }
  3307. const_local_iterator cend(size_type i) const { return end(i); }
  3308. // This is used when resizing
  3309. // --------------------------
  3310. destructive_iterator destructive_begin() { return _mk_destructive_iterator(table.destructive_begin()); }
  3311. destructive_iterator destructive_end() { return _mk_destructive_iterator(table.destructive_end()); }
  3312. // accessor functions for the things we templatize on, basically
  3313. // -------------------------------------------------------------
  3314. hasher hash_funct() const { return settings; }
  3315. key_equal key_eq() const { return key_info; }
  3316. allocator_type get_allocator() const { return table.get_allocator(); }
  3317. // Accessor function for statistics gathering.
  3318. unsigned int num_table_copies() const { return settings.num_ht_copies(); }
  3319. private:
  3320. // This is used as a tag for the copy constructor, saying to destroy its
  3321. // arg We have two ways of destructively copying: with potentially growing
  3322. // the hashtable as we copy, and without. To make sure the outside world
  3323. // can't do a destructive copy, we make the typename private.
  3324. // -----------------------------------------------------------------------
  3325. enum MoveDontCopyT {MoveDontCopy, MoveDontGrow};
  3326. void _squash_deleted()
  3327. {
  3328. // gets rid of any deleted entries we have
  3329. // ---------------------------------------
  3330. if (num_deleted)
  3331. {
  3332. // get rid of deleted before writing
  3333. sparse_hashtable tmp(MoveDontGrow, *this);
  3334. swap(tmp); // now we are tmp
  3335. }
  3336. assert(num_deleted == 0);
  3337. }
  3338. // creating iterators from sparsetable::ne_iterators
  3339. // -------------------------------------------------
  3340. iterator _mk_iterator(ne_it it) const { return it; }
  3341. const_iterator _mk_const_iterator(cne_it it) const { return it; }
  3342. destructive_iterator _mk_destructive_iterator(dest_it it) const { return it; }
  3343. public:
  3344. size_type size() const { return table.num_nonempty(); }
  3345. size_type max_size() const { return table.max_size(); }
  3346. bool empty() const { return size() == 0; }
  3347. size_type bucket_count() const { return table.size(); }
  3348. size_type max_bucket_count() const { return max_size(); }
  3349. // These are tr1 methods. Their idea of 'bucket' doesn't map well to
  3350. // what we do. We just say every bucket has 0 or 1 items in it.
  3351. size_type bucket_size(size_type i) const
  3352. {
  3353. return (size_type)(begin(i) == end(i) ? 0 : 1);
  3354. }
  3355. private:
  3356. // Because of the above, size_type(-1) is never legal; use it for errors
  3357. // ---------------------------------------------------------------------
  3358. static const size_type ILLEGAL_BUCKET = size_type(-1);
  3359. // Used after a string of deletes. Returns true if we actually shrunk.
  3360. // TODO(csilvers): take a delta so we can take into account inserts
  3361. // done after shrinking. Maybe make part of the Settings class?
  3362. // --------------------------------------------------------------------
  3363. bool _maybe_shrink()
  3364. {
  3365. assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two
  3366. assert(bucket_count() >= HT_MIN_BUCKETS);
  3367. bool retval = false;
  3368. // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS,
  3369. // we'll never shrink until you get relatively big, and we'll never
  3370. // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something
  3371. // like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will
  3372. // shrink us down to HT_MIN_BUCKETS buckets, which is too small.
  3373. // ---------------------------------------------------------------
  3374. const size_type num_remain = table.num_nonempty();
  3375. const size_type shrink_threshold = settings.shrink_threshold();
  3376. if (shrink_threshold > 0 && num_remain < shrink_threshold &&
  3377. bucket_count() > HT_DEFAULT_STARTING_BUCKETS)
  3378. {
  3379. const float shrink_factor = settings.shrink_factor();
  3380. size_type sz = (size_type)(bucket_count() / 2); // find how much we should shrink
  3381. while (sz > HT_DEFAULT_STARTING_BUCKETS &&
  3382. num_remain < static_cast<size_type>(sz * shrink_factor))
  3383. {
  3384. sz /= 2; // stay a power of 2
  3385. }
  3386. sparse_hashtable tmp(MoveDontCopy, *this, sz);
  3387. swap(tmp); // now we are tmp
  3388. retval = true;
  3389. }
  3390. settings.set_consider_shrink(false); // because we just considered it
  3391. return retval;
  3392. }
  3393. // We'll let you resize a hashtable -- though this makes us copy all!
  3394. // When you resize, you say, "make it big enough for this many more elements"
  3395. // Returns true if we actually resized, false if size was already ok.
  3396. // --------------------------------------------------------------------------
  3397. bool _resize_delta(size_type delta)
  3398. {
  3399. bool did_resize = false;
  3400. if (settings.consider_shrink())
  3401. {
  3402. // see if lots of deletes happened
  3403. if (_maybe_shrink())
  3404. did_resize = true;
  3405. }
  3406. if (table.num_nonempty() >=
  3407. (std::numeric_limits<size_type>::max)() - delta)
  3408. {
  3409. throw_exception(std::length_error("resize overflow"));
  3410. }
  3411. size_type num_occupied = (size_type)(table.num_nonempty() + num_deleted);
  3412. if (bucket_count() >= HT_MIN_BUCKETS &&
  3413. (num_occupied + delta) <= settings.enlarge_threshold())
  3414. return did_resize; // we're ok as we are
  3415. // Sometimes, we need to resize just to get rid of all the
  3416. // "deleted" buckets that are clogging up the hashtable. So when
  3417. // deciding whether to resize, count the deleted buckets (which
  3418. // are currently taking up room).
  3419. // -------------------------------------------------------------
  3420. const size_type needed_size =
  3421. settings.min_buckets((size_type)(num_occupied + delta), (size_type)0);
  3422. if (needed_size <= bucket_count()) // we have enough buckets
  3423. return did_resize;
  3424. size_type resize_to = settings.min_buckets((size_type)(num_occupied + delta), bucket_count());
  3425. if (resize_to < needed_size && // may double resize_to
  3426. resize_to < (std::numeric_limits<size_type>::max)() / 2)
  3427. {
  3428. // This situation means that we have enough deleted elements,
  3429. // that once we purge them, we won't actually have needed to
  3430. // grow. But we may want to grow anyway: if we just purge one
  3431. // element, say, we'll have to grow anyway next time we
  3432. // insert. Might as well grow now, since we're already going
  3433. // through the trouble of copying (in order to purge the
  3434. // deleted elements).
  3435. const size_type target =
  3436. static_cast<size_type>(settings.shrink_size((size_type)(resize_to*2)));
  3437. if (table.num_nonempty() + delta >= target)
  3438. {
  3439. // Good, we won't be below the shrink threshhold even if we double.
  3440. resize_to *= 2;
  3441. }
  3442. }
  3443. sparse_hashtable tmp(MoveDontCopy, *this, resize_to);
  3444. swap(tmp); // now we are tmp
  3445. return true;
  3446. }
  3447. // Used to actually do the rehashing when we grow/shrink a hashtable
  3448. // -----------------------------------------------------------------
  3449. void _copy_from(const sparse_hashtable &ht, size_type min_buckets_wanted)
  3450. {
  3451. clear(); // clear table, set num_deleted to 0
  3452. // If we need to change the size of our table, do it now
  3453. const size_type resize_to = settings.min_buckets(ht.size(), min_buckets_wanted);
  3454. if (resize_to > bucket_count())
  3455. {
  3456. // we don't have enough buckets
  3457. table.resize(resize_to); // sets the number of buckets
  3458. settings.reset_thresholds(bucket_count());
  3459. }
  3460. // We use a normal iterator to get bcks from ht
  3461. // We could use insert() here, but since we know there are
  3462. // no duplicates, we can be more efficient
  3463. assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
  3464. for (const_iterator it = ht.begin(); it != ht.end(); ++it)
  3465. {
  3466. size_type num_probes = 0; // how many times we've probed
  3467. size_type bucknum;
  3468. const size_type bucket_count_minus_one = bucket_count() - 1;
  3469. for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
  3470. table.test(bucknum); // table.test() OK since no erase()
  3471. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one)
  3472. {
  3473. ++num_probes;
  3474. assert(num_probes < bucket_count()
  3475. && "Hashtable is full: an error in key_equal<> or hash<>");
  3476. }
  3477. table.set(bucknum, *it); // copies the value to here
  3478. }
  3479. settings.inc_num_ht_copies();
  3480. }
  3481. // Implementation is like _copy_from, but it destroys the table of the
  3482. // "from" guy by freeing sparsetable memory as we iterate. This is
  3483. // useful in resizing, since we're throwing away the "from" guy anyway.
  3484. // --------------------------------------------------------------------
  3485. void _move_from(MoveDontCopyT mover, sparse_hashtable &ht,
  3486. size_type min_buckets_wanted)
  3487. {
  3488. clear();
  3489. // If we need to change the size of our table, do it now
  3490. size_type resize_to;
  3491. if (mover == MoveDontGrow)
  3492. resize_to = ht.bucket_count(); // keep same size as old ht
  3493. else // MoveDontCopy
  3494. resize_to = settings.min_buckets(ht.size(), min_buckets_wanted);
  3495. if (resize_to > bucket_count())
  3496. {
  3497. // we don't have enough buckets
  3498. table.resize(resize_to); // sets the number of buckets
  3499. settings.reset_thresholds(bucket_count());
  3500. }
  3501. // We use a normal iterator to get bcks from ht
  3502. // We could use insert() here, but since we know there are
  3503. // no duplicates, we can be more efficient
  3504. assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
  3505. const size_type bucket_count_minus_one = (const size_type)(bucket_count() - 1);
  3506. // THIS IS THE MAJOR LINE THAT DIFFERS FROM COPY_FROM():
  3507. for (destructive_iterator it = ht.destructive_begin();
  3508. it != ht.destructive_end(); ++it)
  3509. {
  3510. size_type num_probes = 0;
  3511. size_type bucknum;
  3512. for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
  3513. table.test(bucknum); // table.test() OK since no erase()
  3514. bucknum = (size_type)((bucknum + JUMP_(key, num_probes)) & (bucket_count()-1)))
  3515. {
  3516. ++num_probes;
  3517. assert(num_probes < bucket_count()
  3518. && "Hashtable is full: an error in key_equal<> or hash<>");
  3519. }
  3520. table.move(bucknum, *it); // moves the value to here
  3521. }
  3522. settings.inc_num_ht_copies();
  3523. }
  3524. // Required by the spec for hashed associative container
  3525. public:
  3526. // Though the docs say this should be num_buckets, I think it's much
  3527. // more useful as num_elements. As a special feature, calling with
  3528. // req_elements==0 will cause us to shrink if we can, saving space.
  3529. // -----------------------------------------------------------------
  3530. void resize(size_type req_elements)
  3531. {
  3532. // resize to this or larger
  3533. if (settings.consider_shrink() || req_elements == 0)
  3534. _maybe_shrink();
  3535. if (req_elements > table.num_nonempty()) // we only grow
  3536. _resize_delta((size_type)(req_elements - table.num_nonempty()));
  3537. }
  3538. // Get and change the value of shrink_factor and enlarge_factor. The
  3539. // description at the beginning of this file explains how to choose
  3540. // the values. Setting the shrink parameter to 0.0 ensures that the
  3541. // table never shrinks.
  3542. // ------------------------------------------------------------------
  3543. void get_resizing_parameters(float* shrink, float* grow) const
  3544. {
  3545. *shrink = settings.shrink_factor();
  3546. *grow = settings.enlarge_factor();
  3547. }
  3548. float get_shrink_factor() const { return settings.shrink_factor(); }
  3549. float get_enlarge_factor() const { return settings.enlarge_factor(); }
  3550. void set_resizing_parameters(float shrink, float grow) {
  3551. settings.set_resizing_parameters(shrink, grow);
  3552. settings.reset_thresholds(bucket_count());
  3553. }
  3554. void set_shrink_factor(float shrink)
  3555. {
  3556. set_resizing_parameters(shrink, get_enlarge_factor());
  3557. }
  3558. void set_enlarge_factor(float grow)
  3559. {
  3560. set_resizing_parameters(get_shrink_factor(), grow);
  3561. }
  3562. // CONSTRUCTORS -- as required by the specs, we take a size,
  3563. // but also let you specify a hashfunction, key comparator,
  3564. // and key extractor. We also define a copy constructor and =.
  3565. // DESTRUCTOR -- the default is fine, surprisingly.
  3566. // ------------------------------------------------------------
  3567. explicit sparse_hashtable(size_type expected_max_items_in_table = 0,
  3568. const HashFcn& hf = HashFcn(),
  3569. const EqualKey& eql = EqualKey(),
  3570. const ExtractKey& ext = ExtractKey(),
  3571. const SetKey& set = SetKey(),
  3572. const Alloc& alloc = Alloc())
  3573. : settings(hf),
  3574. key_info(ext, set, eql),
  3575. num_deleted(0),
  3576. table((expected_max_items_in_table == 0
  3577. ? HT_DEFAULT_STARTING_BUCKETS
  3578. : settings.min_buckets(expected_max_items_in_table, 0)),
  3579. value_alloc_type(alloc))
  3580. {
  3581. settings.reset_thresholds(bucket_count());
  3582. }
  3583. // As a convenience for resize(), we allow an optional second argument
  3584. // which lets you make this new hashtable a different size than ht.
  3585. // We also provide a mechanism of saying you want to "move" the ht argument
  3586. // into us instead of copying.
  3587. // ------------------------------------------------------------------------
  3588. sparse_hashtable(const sparse_hashtable& ht,
  3589. size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
  3590. : settings(ht.settings),
  3591. key_info(ht.key_info),
  3592. num_deleted(0),
  3593. table(0)
  3594. {
  3595. settings.reset_thresholds(bucket_count());
  3596. _copy_from(ht, min_buckets_wanted);
  3597. }
  3598. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  3599. sparse_hashtable(sparse_hashtable&& o) :
  3600. settings(std::move(o.settings)),
  3601. key_info(std::move(o.key_info)),
  3602. num_deleted(o.num_deleted),
  3603. table(std::move(o.table))
  3604. {
  3605. }
  3606. sparse_hashtable(sparse_hashtable&& o, const Alloc& alloc) :
  3607. settings(std::move(o.settings)),
  3608. key_info(std::move(o.key_info)),
  3609. num_deleted(o.num_deleted),
  3610. table(std::move(o.table), alloc)
  3611. {
  3612. }
  3613. sparse_hashtable& operator=(sparse_hashtable&& o)
  3614. {
  3615. using std::swap;
  3616. sparse_hashtable tmp(std::move(o));
  3617. swap(tmp, *this);
  3618. return *this;
  3619. }
  3620. #endif
  3621. sparse_hashtable(MoveDontCopyT mover,
  3622. sparse_hashtable& ht,
  3623. size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
  3624. : settings(ht.settings),
  3625. key_info(ht.key_info),
  3626. num_deleted(0),
  3627. table(min_buckets_wanted, ht.table.get_allocator())
  3628. {
  3629. settings.reset_thresholds(bucket_count());
  3630. _move_from(mover, ht, min_buckets_wanted);
  3631. }
  3632. sparse_hashtable& operator=(const sparse_hashtable& ht)
  3633. {
  3634. if (&ht == this)
  3635. return *this; // don't copy onto ourselves
  3636. settings = ht.settings;
  3637. key_info = ht.key_info;
  3638. num_deleted = ht.num_deleted;
  3639. // _copy_from() calls clear and sets num_deleted to 0 too
  3640. _copy_from(ht, HT_MIN_BUCKETS);
  3641. // we purposefully don't copy the allocator, which may not be copyable
  3642. return *this;
  3643. }
  3644. // Many STL algorithms use swap instead of copy constructors
  3645. void swap(sparse_hashtable& ht)
  3646. {
  3647. using std::swap;
  3648. swap(settings, ht.settings);
  3649. swap(key_info, ht.key_info);
  3650. swap(num_deleted, ht.num_deleted);
  3651. table.swap(ht.table);
  3652. settings.reset_thresholds(bucket_count()); // also resets consider_shrink
  3653. ht.settings.reset_thresholds(ht.bucket_count());
  3654. // we purposefully don't swap the allocator, which may not be swap-able
  3655. }
  3656. // It's always nice to be able to clear a table without deallocating it
  3657. void clear()
  3658. {
  3659. if (!empty() || num_deleted != 0)
  3660. {
  3661. table.clear();
  3662. table = Table(HT_DEFAULT_STARTING_BUCKETS);
  3663. }
  3664. settings.reset_thresholds(bucket_count());
  3665. num_deleted = 0;
  3666. }
  3667. // LOOKUP ROUTINES
  3668. private:
  3669. enum pos_type { pt_empty = 0, pt_erased, pt_full };
  3670. // -------------------------------------------------------------------
  3671. class Position
  3672. {
  3673. public:
  3674. Position() : _t(pt_empty) {}
  3675. Position(pos_type t, size_type idx) : _t(t), _idx(idx) {}
  3676. pos_type _t;
  3677. size_type _idx;
  3678. };
  3679. // Returns a pair:
  3680. // - 'first' is a code, 2 if key already present, 0 or 1 otherwise.
  3681. // - 'second' is a position, where the key should go
  3682. // Note: because of deletions where-to-insert is not trivial: it's the
  3683. // first deleted bucket we see, as long as we don't find the key later
  3684. // -------------------------------------------------------------------
  3685. Position _find_position(const key_type &key) const
  3686. {
  3687. size_type num_probes = 0; // how many times we've probed
  3688. const size_type bucket_count_minus_one = (const size_type)(bucket_count() - 1);
  3689. size_type bucknum = hash(key) & bucket_count_minus_one;
  3690. Position pos;
  3691. while (1)
  3692. {
  3693. // probe until something happens
  3694. // -----------------------------
  3695. typename Table::GrpPos grp_pos(table, bucknum);
  3696. if (!grp_pos.test_strict())
  3697. {
  3698. // bucket is empty => key not present
  3699. return pos._t ? pos : Position(pt_empty, bucknum);
  3700. }
  3701. else if (grp_pos.test())
  3702. {
  3703. reference ref(grp_pos.unsafe_get());
  3704. if (equals(key, get_key(ref)))
  3705. return Position(pt_full, bucknum);
  3706. }
  3707. else if (pos._t == pt_empty)
  3708. {
  3709. // first erased position
  3710. pos._t = pt_erased;
  3711. pos._idx = bucknum;
  3712. }
  3713. ++num_probes; // we're doing another probe
  3714. bucknum = (size_type)((bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one);
  3715. assert(num_probes < bucket_count()
  3716. && "Hashtable is full: an error in key_equal<> or hash<>");
  3717. }
  3718. }
  3719. public:
  3720. // I hate to duplicate find() like that, but it is
  3721. // significantly faster to not have the intermediate pair
  3722. // ------------------------------------------------------------------
  3723. iterator find(const key_type& key)
  3724. {
  3725. size_type num_probes = 0; // how many times we've probed
  3726. const size_type bucket_count_minus_one = bucket_count() - 1;
  3727. size_type bucknum = hash(key) & bucket_count_minus_one;
  3728. while (1) // probe until something happens
  3729. {
  3730. typename Table::GrpPos grp_pos(table, bucknum);
  3731. if (!grp_pos.test_strict())
  3732. return end(); // bucket is empty
  3733. if (grp_pos.test())
  3734. {
  3735. reference ref(grp_pos.unsafe_get());
  3736. if (equals(key, get_key(ref)))
  3737. return grp_pos.get_iter(ref);
  3738. }
  3739. ++num_probes; // we're doing another probe
  3740. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3741. assert(num_probes < bucket_count()
  3742. && "Hashtable is full: an error in key_equal<> or hash<>");
  3743. }
  3744. }
  3745. // Wish I could avoid the duplicate find() const and non-const.
  3746. // ------------------------------------------------------------
  3747. const_iterator find(const key_type& key) const
  3748. {
  3749. size_type num_probes = 0; // how many times we've probed
  3750. const size_type bucket_count_minus_one = bucket_count() - 1;
  3751. size_type bucknum = hash(key) & bucket_count_minus_one;
  3752. while (1) // probe until something happens
  3753. {
  3754. typename Table::GrpPos grp_pos(table, bucknum);
  3755. if (!grp_pos.test_strict())
  3756. return end(); // bucket is empty
  3757. else if (grp_pos.test())
  3758. {
  3759. reference ref(grp_pos.unsafe_get());
  3760. if (equals(key, get_key(ref)))
  3761. return _mk_const_iterator(table.get_iter(bucknum, &ref));
  3762. }
  3763. ++num_probes; // we're doing another probe
  3764. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3765. assert(num_probes < bucket_count()
  3766. && "Hashtable is full: an error in key_equal<> or hash<>");
  3767. }
  3768. }
  3769. // This is a tr1 method: the bucket a given key is in, or what bucket
  3770. // it would be put in, if it were to be inserted. Shrug.
  3771. // ------------------------------------------------------------------
  3772. size_type bucket(const key_type& key) const
  3773. {
  3774. Position pos = _find_position(key);
  3775. return pos._idx;
  3776. }
  3777. // Counts how many elements have key key. For maps, it's either 0 or 1.
  3778. // ---------------------------------------------------------------------
  3779. size_type count(const key_type &key) const
  3780. {
  3781. Position pos = _find_position(key);
  3782. return (size_type)(pos._t == pt_full ? 1 : 0);
  3783. }
  3784. // Likewise, equal_range doesn't really make sense for us. Oh well.
  3785. // -----------------------------------------------------------------
  3786. std::pair<iterator,iterator> equal_range(const key_type& key)
  3787. {
  3788. iterator pos = find(key); // either an iterator or end
  3789. if (pos == end())
  3790. return std::pair<iterator,iterator>(pos, pos);
  3791. else
  3792. {
  3793. const iterator startpos = pos++;
  3794. return std::pair<iterator,iterator>(startpos, pos);
  3795. }
  3796. }
  3797. std::pair<const_iterator,const_iterator> equal_range(const key_type& key) const
  3798. {
  3799. const_iterator pos = find(key); // either an iterator or end
  3800. if (pos == end())
  3801. return std::pair<const_iterator,const_iterator>(pos, pos);
  3802. else
  3803. {
  3804. const const_iterator startpos = pos++;
  3805. return std::pair<const_iterator,const_iterator>(startpos, pos);
  3806. }
  3807. }
  3808. // INSERTION ROUTINES
  3809. private:
  3810. // Private method used by insert_noresize and find_or_insert.
  3811. template <class T>
  3812. reference _insert_at(T& obj, size_type pos, bool erased)
  3813. {
  3814. if (size() >= max_size())
  3815. {
  3816. throw_exception(std::length_error("insert overflow"));
  3817. }
  3818. if (erased)
  3819. {
  3820. assert(num_deleted);
  3821. --num_deleted;
  3822. }
  3823. return table.set(pos, obj);
  3824. }
  3825. // If you know *this is big enough to hold obj, use this routine
  3826. template <class T>
  3827. std::pair<iterator, bool> _insert_noresize(T& obj)
  3828. {
  3829. Position pos = _find_position(get_key(obj));
  3830. bool already_there = (pos._t == pt_full);
  3831. if (!already_there)
  3832. {
  3833. reference ref(_insert_at(obj, pos._idx, pos._t == pt_erased));
  3834. return std::pair<iterator, bool>(_mk_iterator(table.get_iter(pos._idx, &ref)), true);
  3835. }
  3836. return std::pair<iterator,bool>(_mk_iterator(table.get_iter(pos._idx)), false);
  3837. }
  3838. // Specializations of insert(it, it) depending on the power of the iterator:
  3839. // (1) Iterator supports operator-, resize before inserting
  3840. template <class ForwardIterator>
  3841. void _insert(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag /*unused*/)
  3842. {
  3843. int64_t dist = std::distance(f, l);
  3844. if (dist < 0 || static_cast<size_t>(dist) >= (std::numeric_limits<size_type>::max)())
  3845. throw_exception(std::length_error("insert-range overflow"));
  3846. _resize_delta(static_cast<size_type>(dist));
  3847. for (; dist > 0; --dist, ++f)
  3848. _insert_noresize(*f);
  3849. }
  3850. // (2) Arbitrary iterator, can't tell how much to resize
  3851. template <class InputIterator>
  3852. void _insert(InputIterator f, InputIterator l, std::input_iterator_tag /*unused*/)
  3853. {
  3854. for (; f != l; ++f)
  3855. _insert(*f);
  3856. }
  3857. public:
  3858. #if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)
  3859. template <class... Args>
  3860. std::pair<iterator, bool> emplace(Args&&... args)
  3861. {
  3862. _resize_delta(1);
  3863. value_type obj(std::forward<Args>(args)...);
  3864. return _insert_noresize(obj);
  3865. }
  3866. #endif
  3867. // This is the normal insert routine, used by the outside world
  3868. std::pair<iterator, bool> insert(const_reference obj)
  3869. {
  3870. _resize_delta(1); // adding an object, grow if need be
  3871. return _insert_noresize(obj);
  3872. }
  3873. // When inserting a lot at a time, we specialize on the type of iterator
  3874. template <class InputIterator>
  3875. void insert(InputIterator f, InputIterator l)
  3876. {
  3877. // specializes on iterator type
  3878. _insert(f, l,
  3879. typename std::iterator_traits<InputIterator>::iterator_category());
  3880. }
  3881. // DefaultValue is a functor that takes a key and returns a value_type
  3882. // representing the default value to be inserted if none is found.
  3883. template <class DefaultValue>
  3884. value_type& find_or_insert(const key_type& key)
  3885. {
  3886. size_type num_probes = 0; // how many times we've probed
  3887. const size_type bucket_count_minus_one = bucket_count() - 1;
  3888. size_type bucknum = hash(key) & bucket_count_minus_one;
  3889. DefaultValue default_value;
  3890. size_type erased_pos = 0;
  3891. bool erased = false;
  3892. while (1) // probe until something happens
  3893. {
  3894. typename Table::GrpPos grp_pos(table, bucknum);
  3895. if (!grp_pos.test_strict())
  3896. {
  3897. // not found
  3898. if (_resize_delta(1))
  3899. {
  3900. // needed to rehash to make room
  3901. // Since we resized, we can't use pos, so recalculate where to insert.
  3902. value_type def(default_value(key));
  3903. return *(_insert_noresize(def).first);
  3904. }
  3905. else
  3906. {
  3907. // no need to rehash, insert right here
  3908. value_type def(default_value(key));
  3909. return _insert_at(def, erased ? erased_pos : bucknum, erased);
  3910. }
  3911. }
  3912. if (grp_pos.test())
  3913. {
  3914. reference ref(grp_pos.unsafe_get());
  3915. if (equals(key, get_key(ref)))
  3916. return ref;
  3917. }
  3918. else if (!erased)
  3919. {
  3920. // first erased position
  3921. erased_pos = bucknum;
  3922. erased = true;
  3923. }
  3924. ++num_probes; // we're doing another probe
  3925. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3926. assert(num_probes < bucket_count()
  3927. && "Hashtable is full: an error in key_equal<> or hash<>");
  3928. }
  3929. }
  3930. size_type erase(const key_type& key)
  3931. {
  3932. size_type num_probes = 0; // how many times we've probed
  3933. const size_type bucket_count_minus_one = bucket_count() - 1;
  3934. size_type bucknum = hash(key) & bucket_count_minus_one;
  3935. while (1) // probe until something happens
  3936. {
  3937. typename Table::GrpPos grp_pos(table, bucknum);
  3938. if (!grp_pos.test_strict())
  3939. return 0; // bucket is empty, we deleted nothing
  3940. if (grp_pos.test())
  3941. {
  3942. reference ref(grp_pos.unsafe_get());
  3943. if (equals(key, get_key(ref)))
  3944. {
  3945. grp_pos.erase(table);
  3946. ++num_deleted;
  3947. settings.set_consider_shrink(true); // will think about shrink after next insert
  3948. return 1; // because we deleted one thing
  3949. }
  3950. }
  3951. ++num_probes; // we're doing another probe
  3952. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3953. assert(num_probes < bucket_count()
  3954. && "Hashtable is full: an error in key_equal<> or hash<>");
  3955. }
  3956. }
  3957. const_iterator erase(const_iterator pos)
  3958. {
  3959. if (pos == cend())
  3960. return cend(); // sanity check
  3961. const_iterator nextpos = table.erase(pos);
  3962. ++num_deleted;
  3963. settings.set_consider_shrink(true);
  3964. return nextpos;
  3965. }
  3966. const_iterator erase(const_iterator f, const_iterator l)
  3967. {
  3968. if (f == cend())
  3969. return cend(); // sanity check
  3970. size_type num_before = table.num_nonempty();
  3971. const_iterator nextpos = table.erase(f, l);
  3972. num_deleted += num_before - table.num_nonempty();
  3973. settings.set_consider_shrink(true);
  3974. return nextpos;
  3975. }
  3976. // Deleted key routines - just to keep google test framework happy
  3977. // we don't actually use the deleted key
  3978. // ---------------------------------------------------------------
  3979. void set_deleted_key(const key_type& key)
  3980. {
  3981. _squash_deleted();
  3982. key_info.delkey = key;
  3983. }
  3984. void clear_deleted_key()
  3985. {
  3986. _squash_deleted();
  3987. }
  3988. key_type deleted_key() const
  3989. {
  3990. return key_info.delkey;
  3991. }
  3992. bool operator==(const sparse_hashtable& ht) const
  3993. {
  3994. if (this == &ht)
  3995. return true;
  3996. if (size() != ht.size())
  3997. return false;
  3998. for (const_iterator it = begin(); it != end(); ++it)
  3999. {
  4000. const_iterator it2 = ht.find(get_key(*it));
  4001. if ((it2 == ht.end()) || (*it != *it2))
  4002. return false;
  4003. }
  4004. return true;
  4005. }
  4006. bool operator!=(const sparse_hashtable& ht) const
  4007. {
  4008. return !(*this == ht);
  4009. }
  4010. // I/O
  4011. // We support reading and writing hashtables to disk. NOTE that
  4012. // this only stores the hashtable metadata, not the stuff you've
  4013. // actually put in the hashtable! Alas, since I don't know how to
  4014. // write a hasher or key_equal, you have to make sure everything
  4015. // but the table is the same. We compact before writing.
  4016. //
  4017. // The OUTPUT type needs to support a Write() operation. File and
  4018. // OutputBuffer are appropriate types to pass in.
  4019. //
  4020. // The INPUT type needs to support a Read() operation. File and
  4021. // InputBuffer are appropriate types to pass in.
  4022. // -------------------------------------------------------------
  4023. template <typename OUTPUT>
  4024. bool write_metadata(OUTPUT *fp)
  4025. {
  4026. _squash_deleted(); // so we don't have to worry about delkey
  4027. return table.write_metadata(fp);
  4028. }
  4029. template <typename INPUT>
  4030. bool read_metadata(INPUT *fp)
  4031. {
  4032. num_deleted = 0; // since we got rid before writing
  4033. const bool result = table.read_metadata(fp);
  4034. settings.reset_thresholds(bucket_count());
  4035. return result;
  4036. }
  4037. // Only meaningful if value_type is a POD.
  4038. template <typename OUTPUT>
  4039. bool write_nopointer_data(OUTPUT *fp)
  4040. {
  4041. return table.write_nopointer_data(fp);
  4042. }
  4043. // Only meaningful if value_type is a POD.
  4044. template <typename INPUT>
  4045. bool read_nopointer_data(INPUT *fp)
  4046. {
  4047. return table.read_nopointer_data(fp);
  4048. }
  4049. // INPUT and OUTPUT must be either a FILE, *or* a C++ stream
  4050. // (istream, ostream, etc) *or* a class providing
  4051. // Read(void*, size_t) and Write(const void*, size_t)
  4052. // (respectively), which writes a buffer into a stream
  4053. // (which the INPUT/OUTPUT instance presumably owns).
  4054. typedef sparsehash_internal::pod_serializer<value_type> NopointerSerializer;
  4055. // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&)
  4056. template <typename ValueSerializer, typename OUTPUT>
  4057. bool serialize(ValueSerializer serializer, OUTPUT *fp)
  4058. {
  4059. _squash_deleted(); // so we don't have to worry about delkey
  4060. return table.serialize(serializer, fp);
  4061. }
  4062. // ValueSerializer: a functor. operator()(INPUT*, value_type*)
  4063. template <typename ValueSerializer, typename INPUT>
  4064. bool unserialize(ValueSerializer serializer, INPUT *fp)
  4065. {
  4066. num_deleted = 0; // since we got rid before writing
  4067. const bool result = table.unserialize(serializer, fp);
  4068. settings.reset_thresholds(bucket_count());
  4069. return result;
  4070. }
  4071. private:
  4072. // Package templated functors with the other types to eliminate memory
  4073. // needed for storing these zero-size operators. Since ExtractKey and
  4074. // hasher's operator() might have the same function signature, they
  4075. // must be packaged in different classes.
  4076. // -------------------------------------------------------------------------
  4077. struct Settings :
  4078. sparsehash_internal::sh_hashtable_settings<key_type, hasher,
  4079. size_type, HT_MIN_BUCKETS>
  4080. {
  4081. explicit Settings(const hasher& hf)
  4082. : sparsehash_internal::sh_hashtable_settings<key_type, hasher, size_type,
  4083. HT_MIN_BUCKETS>
  4084. (hf, HT_OCCUPANCY_PCT / 100.0f, HT_EMPTY_PCT / 100.0f) {}
  4085. };
  4086. // KeyInfo stores delete key and packages zero-size functors:
  4087. // ExtractKey and SetKey.
  4088. // ---------------------------------------------------------
  4089. class KeyInfo : public ExtractKey, public SetKey, public EqualKey
  4090. {
  4091. public:
  4092. KeyInfo(const ExtractKey& ek, const SetKey& sk, const EqualKey& eq)
  4093. : ExtractKey(ek), SetKey(sk), EqualKey(eq)
  4094. {
  4095. }
  4096. // We want to return the exact same type as ExtractKey: Key or const Key&
  4097. typename ExtractKey::result_type get_key(const_reference v) const
  4098. {
  4099. return ExtractKey::operator()(v);
  4100. }
  4101. bool equals(const key_type& a, const key_type& b) const
  4102. {
  4103. return EqualKey::operator()(a, b);
  4104. }
  4105. typename spp_::remove_const<key_type>::type delkey;
  4106. };
  4107. // Utility functions to access the templated operators
  4108. size_t hash(const key_type& v) const
  4109. {
  4110. return settings.hash(v);
  4111. }
  4112. bool equals(const key_type& a, const key_type& b) const
  4113. {
  4114. return key_info.equals(a, b);
  4115. }
  4116. typename ExtractKey::result_type get_key(const_reference v) const
  4117. {
  4118. return key_info.get_key(v);
  4119. }
  4120. private:
  4121. // Actual data
  4122. // -----------
  4123. Settings settings;
  4124. KeyInfo key_info;
  4125. size_type num_deleted;
  4126. Table table; // holds num_buckets and num_elements too
  4127. };
  4128. // We need a global swap as well
  4129. // -----------------------------
  4130. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4131. inline void swap(sparse_hashtable<V,K,HF,ExK,SetK,EqK,A> &x,
  4132. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A> &y)
  4133. {
  4134. x.swap(y);
  4135. }
  4136. #undef JUMP_
  4137. // -----------------------------------------------------------------------------
  4138. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4139. const typename sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::size_type
  4140. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::ILLEGAL_BUCKET;
  4141. // How full we let the table get before we resize. Knuth says .8 is
  4142. // good -- higher causes us to probe too much, though saves memory
  4143. // -----------------------------------------------------------------------------
  4144. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4145. const int sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_PCT = 50;
  4146. // How empty we let the table get before we resize lower.
  4147. // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing
  4148. // -----------------------------------------------------------------------------
  4149. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4150. const int sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_EMPTY_PCT
  4151. = static_cast<int>(0.4 *
  4152. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_PCT);
  4153. // ----------------------------------------------------------------------
  4154. // S P A R S E _ H A S H _ M A P
  4155. // ----------------------------------------------------------------------
  4156. template <class Key, class T,
  4157. class HashFcn = spp_hash<Key>,
  4158. class EqualKey = std::equal_to<Key>,
  4159. class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
  4160. class sparse_hash_map
  4161. {
  4162. private:
  4163. // Apparently select1st is not stl-standard, so we define our own
  4164. struct SelectKey
  4165. {
  4166. typedef const Key& result_type;
  4167. inline const Key& operator()(const std::pair<const Key, T>& p) const
  4168. {
  4169. return p.first;
  4170. }
  4171. };
  4172. struct SetKey
  4173. {
  4174. inline void operator()(std::pair<const Key, T>* value, const Key& new_key) const
  4175. {
  4176. *const_cast<Key*>(&value->first) = new_key;
  4177. }
  4178. };
  4179. // For operator[].
  4180. struct DefaultValue
  4181. {
  4182. inline std::pair<const Key, T> operator()(const Key& key) const
  4183. {
  4184. return std::make_pair(key, T());
  4185. }
  4186. };
  4187. // The actual data
  4188. typedef sparse_hashtable<std::pair<typename spp_::remove_const<Key>::type, T>, Key, HashFcn, SelectKey,
  4189. SetKey, EqualKey, Alloc> ht;
  4190. public:
  4191. typedef typename ht::key_type key_type;
  4192. typedef T data_type;
  4193. typedef T mapped_type;
  4194. typedef typename std::pair<const Key, T> value_type;
  4195. typedef typename ht::hasher hasher;
  4196. typedef typename ht::key_equal key_equal;
  4197. typedef Alloc allocator_type;
  4198. typedef typename ht::size_type size_type;
  4199. typedef typename ht::difference_type difference_type;
  4200. typedef typename ht::pointer pointer;
  4201. typedef typename ht::const_pointer const_pointer;
  4202. typedef typename ht::reference reference;
  4203. typedef typename ht::const_reference const_reference;
  4204. typedef typename ht::iterator iterator;
  4205. typedef typename ht::const_iterator const_iterator;
  4206. typedef typename ht::local_iterator local_iterator;
  4207. typedef typename ht::const_local_iterator const_local_iterator;
  4208. // Iterator functions
  4209. iterator begin() { return rep.begin(); }
  4210. iterator end() { return rep.end(); }
  4211. const_iterator begin() const { return rep.cbegin(); }
  4212. const_iterator end() const { return rep.cend(); }
  4213. const_iterator cbegin() const { return rep.cbegin(); }
  4214. const_iterator cend() const { return rep.cend(); }
  4215. // These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
  4216. local_iterator begin(size_type i) { return rep.begin(i); }
  4217. local_iterator end(size_type i) { return rep.end(i); }
  4218. const_local_iterator begin(size_type i) const { return rep.begin(i); }
  4219. const_local_iterator end(size_type i) const { return rep.end(i); }
  4220. const_local_iterator cbegin(size_type i) const { return rep.cbegin(i); }
  4221. const_local_iterator cend(size_type i) const { return rep.cend(i); }
  4222. // Accessor functions
  4223. // ------------------
  4224. allocator_type get_allocator() const { return rep.get_allocator(); }
  4225. hasher hash_funct() const { return rep.hash_funct(); }
  4226. hasher hash_function() const { return hash_funct(); }
  4227. key_equal key_eq() const { return rep.key_eq(); }
  4228. // Constructors
  4229. // ------------
  4230. explicit sparse_hash_map(size_type n = 0,
  4231. const hasher& hf = hasher(),
  4232. const key_equal& eql = key_equal(),
  4233. const allocator_type& alloc = allocator_type())
  4234. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4235. {
  4236. }
  4237. explicit sparse_hash_map(const allocator_type& alloc) :
  4238. rep(0, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4239. {
  4240. }
  4241. sparse_hash_map(size_type n, const allocator_type& alloc) :
  4242. rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4243. {
  4244. }
  4245. sparse_hash_map(size_type n, const hasher& hf, const allocator_type& alloc) :
  4246. rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4247. {
  4248. }
  4249. template <class InputIterator>
  4250. sparse_hash_map(InputIterator f, InputIterator l,
  4251. size_type n = 0,
  4252. const hasher& hf = hasher(),
  4253. const key_equal& eql = key_equal(),
  4254. const allocator_type& alloc = allocator_type())
  4255. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4256. {
  4257. rep.insert(f, l);
  4258. }
  4259. template <class InputIterator>
  4260. sparse_hash_map(InputIterator f, InputIterator l,
  4261. size_type n, const allocator_type& alloc)
  4262. : rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4263. {
  4264. rep.insert(f, l);
  4265. }
  4266. template <class InputIterator>
  4267. sparse_hash_map(InputIterator f, InputIterator l,
  4268. size_type n, const hasher& hf, const allocator_type& alloc)
  4269. : rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4270. {
  4271. rep.insert(f, l);
  4272. }
  4273. sparse_hash_map(const sparse_hash_map &o) :
  4274. rep(o.rep)
  4275. {}
  4276. sparse_hash_map(const sparse_hash_map &o,
  4277. const allocator_type& alloc) :
  4278. rep(o.rep, alloc)
  4279. {}
  4280. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  4281. sparse_hash_map(const sparse_hash_map &&o) :
  4282. rep(std::move(o.rep))
  4283. {}
  4284. sparse_hash_map(const sparse_hash_map &&o,
  4285. const allocator_type& alloc) :
  4286. rep(std::move(o.rep), alloc)
  4287. {}
  4288. #endif
  4289. #if !defined(SPP_NO_CXX11_HDR_INITIALIZER_LIST)
  4290. sparse_hash_map(std::initializer_list<value_type> init,
  4291. size_type n = 0,
  4292. const hasher& hf = hasher(),
  4293. const key_equal& eql = key_equal(),
  4294. const allocator_type& alloc = allocator_type())
  4295. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4296. {
  4297. rep.insert(init.begin(), init.end());
  4298. }
  4299. sparse_hash_map(std::initializer_list<value_type> init,
  4300. size_type n, const allocator_type& alloc) :
  4301. rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4302. {
  4303. rep.insert(init.begin(), init.end());
  4304. }
  4305. sparse_hash_map(std::initializer_list<value_type> init,
  4306. size_type n, const hasher& hf, const allocator_type& alloc) :
  4307. rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4308. {
  4309. rep.insert(init.begin(), init.end());
  4310. }
  4311. sparse_hash_map& operator=(std::initializer_list<value_type> init)
  4312. {
  4313. rep.clear();
  4314. rep.insert(init.begin(), init.end());
  4315. return *this;
  4316. }
  4317. void insert(std::initializer_list<value_type> init)
  4318. {
  4319. rep.insert(init.begin(), init.end());
  4320. }
  4321. #endif
  4322. sparse_hash_map& operator=(const sparse_hash_map &o)
  4323. {
  4324. rep = o.rep;
  4325. return *this;
  4326. }
  4327. void clear() { rep.clear(); }
  4328. void swap(sparse_hash_map& hs) { rep.swap(hs.rep); }
  4329. // Functions concerning size
  4330. // -------------------------
  4331. size_type size() const { return rep.size(); }
  4332. size_type max_size() const { return rep.max_size(); }
  4333. bool empty() const { return rep.empty(); }
  4334. size_type bucket_count() const { return rep.bucket_count(); }
  4335. size_type max_bucket_count() const { return rep.max_bucket_count(); }
  4336. size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
  4337. size_type bucket(const key_type& key) const { return rep.bucket(key); }
  4338. float load_factor() const { return size() * 1.0f / bucket_count(); }
  4339. float max_load_factor() const { return rep.get_enlarge_factor(); }
  4340. void max_load_factor(float grow) { rep.set_enlarge_factor(grow); }
  4341. float min_load_factor() const { return rep.get_shrink_factor(); }
  4342. void min_load_factor(float shrink){ rep.set_shrink_factor(shrink); }
  4343. void set_resizing_parameters(float shrink, float grow)
  4344. {
  4345. rep.set_resizing_parameters(shrink, grow);
  4346. }
  4347. void resize(size_type cnt) { rep.resize(cnt); }
  4348. void rehash(size_type cnt) { resize(cnt); } // c++11 name
  4349. void reserve(size_type cnt) { resize(cnt); } // c++11
  4350. // Lookup
  4351. // ------
  4352. iterator find(const key_type& key) { return rep.find(key); }
  4353. const_iterator find(const key_type& key) const { return rep.find(key); }
  4354. mapped_type& operator[](const key_type& key)
  4355. {
  4356. return rep.template find_or_insert<DefaultValue>(key).second;
  4357. }
  4358. size_type count(const key_type& key) const { return rep.count(key); }
  4359. std::pair<iterator, iterator>
  4360. equal_range(const key_type& key) { return rep.equal_range(key); }
  4361. std::pair<const_iterator, const_iterator>
  4362. equal_range(const key_type& key) const { return rep.equal_range(key); }
  4363. mapped_type& at(const key_type& key)
  4364. {
  4365. iterator it = rep.find(key);
  4366. if (it == rep.end())
  4367. throw_exception(std::out_of_range("at: key not present"));
  4368. return it->second;
  4369. }
  4370. const mapped_type& at(const key_type& key) const
  4371. {
  4372. const_iterator it = rep.find(key);
  4373. if (it == rep.cend())
  4374. throw_exception(std::out_of_range("at: key not present"));
  4375. return it->second;
  4376. }
  4377. #if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)
  4378. template <class... Args>
  4379. std::pair<iterator, bool> emplace(Args&&... args)
  4380. {
  4381. return rep.emplace(std::forward<Args>(args)...);
  4382. }
  4383. template <class... Args>
  4384. iterator emplace_hint(const_iterator , Args&&... args)
  4385. {
  4386. return rep.emplace(std::forward<Args>(args)...).first;
  4387. }
  4388. #endif
  4389. // Insert
  4390. // ------
  4391. std::pair<iterator, bool>
  4392. insert(const value_type& obj) { return rep.insert(obj); }
  4393. template <class InputIterator>
  4394. void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
  4395. void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
  4396. iterator insert(iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4397. iterator insert(const_iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4398. // Deleted key routines - just to keep google test framework happy
  4399. // we don't actually use the deleted key
  4400. // ---------------------------------------------------------------
  4401. void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
  4402. void clear_deleted_key() { rep.clear_deleted_key(); }
  4403. key_type deleted_key() const { return rep.deleted_key(); }
  4404. // Erase
  4405. // -----
  4406. size_type erase(const key_type& key) { return rep.erase(key); }
  4407. iterator erase(iterator it) { return rep.erase(it); }
  4408. iterator erase(iterator f, iterator l) { return rep.erase(f, l); }
  4409. iterator erase(const_iterator it) { return rep.erase(it); }
  4410. iterator erase(const_iterator f, const_iterator l){ return rep.erase(f, l); }
  4411. // Comparison
  4412. // ----------
  4413. bool operator==(const sparse_hash_map& hs) const { return rep == hs.rep; }
  4414. bool operator!=(const sparse_hash_map& hs) const { return rep != hs.rep; }
  4415. // I/O -- this is an add-on for writing metainformation to disk
  4416. //
  4417. // For maximum flexibility, this does not assume a particular
  4418. // file type (though it will probably be a FILE *). We just pass
  4419. // the fp through to rep.
  4420. // If your keys and values are simple enough, you can pass this
  4421. // serializer to serialize()/unserialize(). "Simple enough" means
  4422. // value_type is a POD type that contains no pointers. Note,
  4423. // however, we don't try to normalize endianness.
  4424. // ---------------------------------------------------------------
  4425. typedef typename ht::NopointerSerializer NopointerSerializer;
  4426. // serializer: a class providing operator()(OUTPUT*, const value_type&)
  4427. // (writing value_type to OUTPUT). You can specify a
  4428. // NopointerSerializer object if appropriate (see above).
  4429. // fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
  4430. // pointer to a class providing size_t Write(const void*, size_t),
  4431. // which writes a buffer into a stream (which fp presumably
  4432. // owns) and returns the number of bytes successfully written.
  4433. // Note basic_ostream<not_char> is not currently supported.
  4434. // ---------------------------------------------------------------
  4435. template <typename ValueSerializer, typename OUTPUT>
  4436. bool serialize(ValueSerializer serializer, OUTPUT* fp)
  4437. {
  4438. return rep.serialize(serializer, fp);
  4439. }
  4440. // serializer: a functor providing operator()(INPUT*, value_type*)
  4441. // (reading from INPUT and into value_type). You can specify a
  4442. // NopointerSerializer object if appropriate (see above).
  4443. // fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
  4444. // pointer to a class providing size_t Read(void*, size_t),
  4445. // which reads into a buffer from a stream (which fp presumably
  4446. // owns) and returns the number of bytes successfully read.
  4447. // Note basic_istream<not_char> is not currently supported.
  4448. // NOTE: Since value_type is std::pair<const Key, T>, ValueSerializer
  4449. // may need to do a const cast in order to fill in the key.
  4450. // NOTE: if Key or T are not POD types, the serializer MUST use
  4451. // placement-new to initialize their values, rather than a normal
  4452. // equals-assignment or similar. (The value_type* passed into the
  4453. // serializer points to garbage memory.)
  4454. // ---------------------------------------------------------------
  4455. template <typename ValueSerializer, typename INPUT>
  4456. bool unserialize(ValueSerializer serializer, INPUT* fp)
  4457. {
  4458. return rep.unserialize(serializer, fp);
  4459. }
  4460. // The four methods below are DEPRECATED.
  4461. // Use serialize() and unserialize() for new code.
  4462. // -----------------------------------------------
  4463. template <typename OUTPUT>
  4464. bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
  4465. template <typename INPUT>
  4466. bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
  4467. template <typename OUTPUT>
  4468. bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
  4469. template <typename INPUT>
  4470. bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
  4471. private:
  4472. // The actual data
  4473. // ---------------
  4474. ht rep;
  4475. };
  4476. // We need a global swap as well
  4477. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  4478. inline void swap(sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
  4479. sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
  4480. {
  4481. hm1.swap(hm2);
  4482. }
  4483. // ----------------------------------------------------------------------
  4484. // S P A R S E _ H A S H _ S E T
  4485. // ----------------------------------------------------------------------
  4486. template <class Value,
  4487. class HashFcn = spp_hash<Value>,
  4488. class EqualKey = std::equal_to<Value>,
  4489. class Alloc = libc_allocator_with_realloc<Value> >
  4490. class sparse_hash_set
  4491. {
  4492. private:
  4493. // Apparently identity is not stl-standard, so we define our own
  4494. struct Identity
  4495. {
  4496. typedef const Value& result_type;
  4497. const Value& operator()(const Value& v) const { return v; }
  4498. };
  4499. struct SetKey
  4500. {
  4501. void operator()(Value* value, const Value& new_key) const
  4502. {
  4503. *value = new_key;
  4504. }
  4505. };
  4506. typedef sparse_hashtable<Value, Value, HashFcn, Identity, SetKey,
  4507. EqualKey, Alloc> ht;
  4508. public:
  4509. typedef typename ht::key_type key_type;
  4510. typedef typename ht::value_type value_type;
  4511. typedef typename ht::hasher hasher;
  4512. typedef typename ht::key_equal key_equal;
  4513. typedef Alloc allocator_type;
  4514. typedef typename ht::size_type size_type;
  4515. typedef typename ht::difference_type difference_type;
  4516. typedef typename ht::const_pointer pointer;
  4517. typedef typename ht::const_pointer const_pointer;
  4518. typedef typename ht::const_reference reference;
  4519. typedef typename ht::const_reference const_reference;
  4520. typedef typename ht::const_iterator iterator;
  4521. typedef typename ht::const_iterator const_iterator;
  4522. typedef typename ht::const_local_iterator local_iterator;
  4523. typedef typename ht::const_local_iterator const_local_iterator;
  4524. // Iterator functions -- recall all iterators are const
  4525. iterator begin() const { return rep.begin(); }
  4526. iterator end() const { return rep.end(); }
  4527. const_iterator cbegin() const { return rep.cbegin(); }
  4528. const_iterator cend() const { return rep.cend(); }
  4529. // These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
  4530. local_iterator begin(size_type i) const { return rep.begin(i); }
  4531. local_iterator end(size_type i) const { return rep.end(i); }
  4532. local_iterator cbegin(size_type i) const { return rep.cbegin(i); }
  4533. local_iterator cend(size_type i) const { return rep.cend(i); }
  4534. // Accessor functions
  4535. // ------------------
  4536. allocator_type get_allocator() const { return rep.get_allocator(); }
  4537. hasher hash_funct() const { return rep.hash_funct(); }
  4538. hasher hash_function() const { return hash_funct(); } // tr1 name
  4539. key_equal key_eq() const { return rep.key_eq(); }
  4540. // Constructors
  4541. // ------------
  4542. explicit sparse_hash_set(size_type n = 0,
  4543. const hasher& hf = hasher(),
  4544. const key_equal& eql = key_equal(),
  4545. const allocator_type& alloc = allocator_type()) :
  4546. rep(n, hf, eql, Identity(), SetKey(), alloc)
  4547. {
  4548. }
  4549. explicit sparse_hash_set(const allocator_type& alloc) :
  4550. rep(0, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4551. {
  4552. }
  4553. sparse_hash_set(size_type n, const allocator_type& alloc) :
  4554. rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4555. {
  4556. }
  4557. sparse_hash_set(size_type n, const hasher& hf,
  4558. const allocator_type& alloc) :
  4559. rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4560. {
  4561. }
  4562. template <class InputIterator>
  4563. sparse_hash_set(InputIterator f, InputIterator l,
  4564. size_type n = 0,
  4565. const hasher& hf = hasher(),
  4566. const key_equal& eql = key_equal(),
  4567. const allocator_type& alloc = allocator_type())
  4568. : rep(n, hf, eql, Identity(), SetKey(), alloc)
  4569. {
  4570. rep.insert(f, l);
  4571. }
  4572. template <class InputIterator>
  4573. sparse_hash_set(InputIterator f, InputIterator l,
  4574. size_type n, const allocator_type& alloc)
  4575. : rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4576. {
  4577. rep.insert(f, l);
  4578. }
  4579. template <class InputIterator>
  4580. sparse_hash_set(InputIterator f, InputIterator l,
  4581. size_type n, const hasher& hf, const allocator_type& alloc)
  4582. : rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4583. {
  4584. rep.insert(f, l);
  4585. }
  4586. sparse_hash_set(const sparse_hash_set &o) :
  4587. rep(o.rep)
  4588. {}
  4589. sparse_hash_set(const sparse_hash_set &o,
  4590. const allocator_type& alloc) :
  4591. rep(o.rep, alloc)
  4592. {}
  4593. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  4594. sparse_hash_set(const sparse_hash_set &&o) :
  4595. rep(std::move(o.rep))
  4596. {}
  4597. sparse_hash_set(const sparse_hash_set &&o,
  4598. const allocator_type& alloc) :
  4599. rep(std::move(o.rep), alloc)
  4600. {}
  4601. #endif
  4602. #if !defined(SPP_NO_CXX11_HDR_INITIALIZER_LIST)
  4603. sparse_hash_set(std::initializer_list<value_type> init,
  4604. size_type n = 0,
  4605. const hasher& hf = hasher(),
  4606. const key_equal& eql = key_equal(),
  4607. const allocator_type& alloc = allocator_type()) :
  4608. rep(n, hf, eql, Identity(), SetKey(), alloc)
  4609. {
  4610. rep.insert(init.begin(), init.end());
  4611. }
  4612. sparse_hash_set(std::initializer_list<value_type> init,
  4613. size_type n, const allocator_type& alloc) :
  4614. rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4615. {
  4616. rep.insert(init.begin(), init.end());
  4617. }
  4618. sparse_hash_set(std::initializer_list<value_type> init,
  4619. size_type n, const hasher& hf,
  4620. const allocator_type& alloc) :
  4621. rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4622. {
  4623. rep.insert(init.begin(), init.end());
  4624. }
  4625. sparse_hash_set& operator=(std::initializer_list<value_type> init)
  4626. {
  4627. rep.clear();
  4628. rep.insert(init.begin(), init.end());
  4629. return *this;
  4630. }
  4631. void insert(std::initializer_list<value_type> init)
  4632. {
  4633. rep.insert(init.begin(), init.end());
  4634. }
  4635. #endif
  4636. sparse_hash_set& operator=(const sparse_hash_set &o)
  4637. {
  4638. rep = o.rep;
  4639. return *this;
  4640. }
  4641. void clear() { rep.clear(); }
  4642. void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
  4643. // Functions concerning size
  4644. // -------------------------
  4645. size_type size() const { return rep.size(); }
  4646. size_type max_size() const { return rep.max_size(); }
  4647. bool empty() const { return rep.empty(); }
  4648. size_type bucket_count() const { return rep.bucket_count(); }
  4649. size_type max_bucket_count() const { return rep.max_bucket_count(); }
  4650. size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
  4651. size_type bucket(const key_type& key) const { return rep.bucket(key); }
  4652. float load_factor() const { return size() * 1.0f / bucket_count(); }
  4653. float max_load_factor() const { return rep.get_enlarge_factor(); }
  4654. void max_load_factor(float grow) { rep.set_enlarge_factor(grow); }
  4655. float min_load_factor() const { return rep.get_shrink_factor(); }
  4656. void min_load_factor(float shrink){ rep.set_shrink_factor(shrink); }
  4657. void set_resizing_parameters(float shrink, float grow)
  4658. {
  4659. rep.set_resizing_parameters(shrink, grow);
  4660. }
  4661. void resize(size_type cnt) { rep.resize(cnt); }
  4662. void rehash(size_type cnt) { resize(cnt); } // c++11 name
  4663. void reserve(size_type cnt) { resize(cnt); } // c++11
  4664. // Lookup
  4665. // ------
  4666. iterator find(const key_type& key) const { return rep.find(key); }
  4667. size_type count(const key_type& key) const { return rep.count(key); }
  4668. std::pair<iterator, iterator>
  4669. equal_range(const key_type& key) const { return rep.equal_range(key); }
  4670. #if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)
  4671. template <class... Args>
  4672. std::pair<iterator, bool> emplace(Args&&... args)
  4673. {
  4674. return rep.emplace(std::forward<Args>(args)...);
  4675. }
  4676. template <class... Args>
  4677. iterator emplace_hint(const_iterator , Args&&... args)
  4678. {
  4679. return rep.emplace(std::forward<Args>(args)...).first;
  4680. }
  4681. #endif
  4682. // Insert
  4683. // ------
  4684. std::pair<iterator, bool> insert(const value_type& obj)
  4685. {
  4686. std::pair<typename ht::iterator, bool> p = rep.insert(obj);
  4687. return std::pair<iterator, bool>(p.first, p.second); // const to non-const
  4688. }
  4689. template <class InputIterator>
  4690. void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
  4691. void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
  4692. iterator insert(iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4693. // Deleted key - do nothing - just to keep google test framework happy
  4694. // -------------------------------------------------------------------
  4695. void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
  4696. void clear_deleted_key() { rep.clear_deleted_key(); }
  4697. key_type deleted_key() const { return rep.deleted_key(); }
  4698. // Erase
  4699. // -----
  4700. size_type erase(const key_type& key) { return rep.erase(key); }
  4701. iterator erase(iterator it) { return rep.erase(it); }
  4702. iterator erase(iterator f, iterator l) { return rep.erase(f, l); }
  4703. // Comparison
  4704. // ----------
  4705. bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
  4706. bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
  4707. // I/O -- this is an add-on for writing metainformation to disk
  4708. //
  4709. // For maximum flexibility, this does not assume a particular
  4710. // file type (though it will probably be a FILE *). We just pass
  4711. // the fp through to rep.
  4712. // If your keys and values are simple enough, you can pass this
  4713. // serializer to serialize()/unserialize(). "Simple enough" means
  4714. // value_type is a POD type that contains no pointers. Note,
  4715. // however, we don't try to normalize endianness.
  4716. // ---------------------------------------------------------------
  4717. typedef typename ht::NopointerSerializer NopointerSerializer;
  4718. // serializer: a class providing operator()(OUTPUT*, const value_type&)
  4719. // (writing value_type to OUTPUT). You can specify a
  4720. // NopointerSerializer object if appropriate (see above).
  4721. // fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
  4722. // pointer to a class providing size_t Write(const void*, size_t),
  4723. // which writes a buffer into a stream (which fp presumably
  4724. // owns) and returns the number of bytes successfully written.
  4725. // Note basic_ostream<not_char> is not currently supported.
  4726. // ---------------------------------------------------------------
  4727. template <typename ValueSerializer, typename OUTPUT>
  4728. bool serialize(ValueSerializer serializer, OUTPUT* fp)
  4729. {
  4730. return rep.serialize(serializer, fp);
  4731. }
  4732. // serializer: a functor providing operator()(INPUT*, value_type*)
  4733. // (reading from INPUT and into value_type). You can specify a
  4734. // NopointerSerializer object if appropriate (see above).
  4735. // fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
  4736. // pointer to a class providing size_t Read(void*, size_t),
  4737. // which reads into a buffer from a stream (which fp presumably
  4738. // owns) and returns the number of bytes successfully read.
  4739. // Note basic_istream<not_char> is not currently supported.
  4740. // NOTE: Since value_type is const Key, ValueSerializer
  4741. // may need to do a const cast in order to fill in the key.
  4742. // NOTE: if Key is not a POD type, the serializer MUST use
  4743. // placement-new to initialize its value, rather than a normal
  4744. // equals-assignment or similar. (The value_type* passed into
  4745. // the serializer points to garbage memory.)
  4746. // ---------------------------------------------------------------
  4747. template <typename ValueSerializer, typename INPUT>
  4748. bool unserialize(ValueSerializer serializer, INPUT* fp)
  4749. {
  4750. return rep.unserialize(serializer, fp);
  4751. }
  4752. // The four methods below are DEPRECATED.
  4753. // Use serialize() and unserialize() for new code.
  4754. // -----------------------------------------------
  4755. template <typename OUTPUT>
  4756. bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
  4757. template <typename INPUT>
  4758. bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
  4759. template <typename OUTPUT>
  4760. bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
  4761. template <typename INPUT>
  4762. bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
  4763. private:
  4764. // The actual data
  4765. // ---------------
  4766. ht rep;
  4767. };
  4768. template <class Val, class HashFcn, class EqualKey, class Alloc>
  4769. inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
  4770. sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2)
  4771. {
  4772. hs1.swap(hs2);
  4773. }
  4774. SPP_END_NAMESPACE
  4775. #endif // sparsepp_h_guard_