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.

5626 lines
205 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. #define SPP_INLINE
  774. #ifndef SPP_NAMESPACE
  775. #define SPP_NAMESPACE spp
  776. #endif
  777. namespace SPP_NAMESPACE
  778. {
  779. template <class T>
  780. struct spp_hash
  781. {
  782. SPP_INLINE size_t operator()(const T &__v) const SPP_NOEXCEPT
  783. {
  784. SPP_HASH_CLASS<T> hasher;
  785. return hasher(__v);
  786. }
  787. };
  788. template <class T>
  789. struct spp_hash<T *>
  790. {
  791. static size_t spp_log2 (size_t val) SPP_NOEXCEPT
  792. {
  793. size_t res = 0;
  794. while (val > 1)
  795. {
  796. val >>= 1;
  797. res++;
  798. }
  799. return res;
  800. }
  801. SPP_INLINE size_t operator()(const T *__v) const SPP_NOEXCEPT
  802. {
  803. static const size_t shift = spp_log2(1 + sizeof(T));
  804. return static_cast<size_t>((*(reinterpret_cast<const uintptr_t *>(&__v))) >> shift);
  805. }
  806. };
  807. template <>
  808. struct spp_hash<bool> : public std::unary_function<bool, size_t>
  809. {
  810. SPP_INLINE size_t operator()(bool __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  811. };
  812. template <>
  813. struct spp_hash<char> : public std::unary_function<char, size_t>
  814. {
  815. SPP_INLINE size_t operator()(char __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  816. };
  817. template <>
  818. struct spp_hash<signed char> : public std::unary_function<signed char, size_t>
  819. {
  820. SPP_INLINE size_t operator()(signed char __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  821. };
  822. template <>
  823. struct spp_hash<unsigned char> : public std::unary_function<unsigned char, size_t>
  824. {
  825. SPP_INLINE size_t operator()(unsigned char __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  826. };
  827. template <>
  828. struct spp_hash<wchar_t> : public std::unary_function<wchar_t, size_t>
  829. {
  830. SPP_INLINE size_t operator()(wchar_t __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  831. };
  832. template <>
  833. struct spp_hash<short> : public std::unary_function<short, size_t>
  834. {
  835. SPP_INLINE size_t operator()(short __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  836. };
  837. template <>
  838. struct spp_hash<unsigned short> : public std::unary_function<unsigned short, size_t>
  839. {
  840. SPP_INLINE size_t operator()(unsigned short __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  841. };
  842. template <>
  843. struct spp_hash<int> : public std::unary_function<int, size_t>
  844. {
  845. SPP_INLINE size_t operator()(int __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  846. };
  847. template <>
  848. struct spp_hash<unsigned int> : public std::unary_function<unsigned int, size_t>
  849. {
  850. SPP_INLINE size_t operator()(unsigned int __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  851. };
  852. template <>
  853. struct spp_hash<long> : public std::unary_function<long, size_t>
  854. {
  855. SPP_INLINE size_t operator()(long __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  856. };
  857. template <>
  858. struct spp_hash<unsigned long> : public std::unary_function<unsigned long, size_t>
  859. {
  860. SPP_INLINE size_t operator()(unsigned long __v) const SPP_NOEXCEPT {return static_cast<size_t>(__v);}
  861. };
  862. template <>
  863. struct spp_hash<float> : public std::unary_function<float, size_t>
  864. {
  865. SPP_INLINE size_t operator()(float __v) const SPP_NOEXCEPT
  866. {
  867. // -0.0 and 0.0 should return same hash
  868. uint32_t *as_int = reinterpret_cast<uint32_t *>(&__v);
  869. return (__v == 0) ? static_cast<size_t>(0) : static_cast<size_t>(*as_int);
  870. }
  871. };
  872. #if 0
  873. // todo: we should not ignore half of the double => see libcxx/include/functional
  874. template <>
  875. struct spp_hash<double> : public std::unary_function<double, size_t>
  876. {
  877. SPP_INLINE size_t operator()(double __v) const SPP_NOEXCEPT
  878. {
  879. // -0.0 and 0.0 should return same hash
  880. return (__v == 0) ? (size_t)0 : (size_t)*((uint64_t *)&__v);
  881. }
  882. };
  883. #endif
  884. template <class T, int sz> struct Combiner
  885. {
  886. inline void operator()(T& seed, T value);
  887. };
  888. template <class T> struct Combiner<T, 4>
  889. {
  890. inline void operator()(T& seed, T value)
  891. {
  892. seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  893. }
  894. };
  895. template <class T> struct Combiner<T, 8>
  896. {
  897. inline void operator()(T& seed, T value)
  898. {
  899. seed ^= value + T(0xc6a4a7935bd1e995) + (seed << 6) + (seed >> 2);
  900. }
  901. };
  902. template <class T>
  903. inline void hash_combine(std::size_t& seed, T const& v)
  904. {
  905. spp::spp_hash<T> hasher;
  906. Combiner<std::size_t, sizeof(std::size_t)> combiner;
  907. combiner(seed, hasher(v));
  908. }
  909. };
  910. #endif // spp_utils_h_guard_
  911. SPP_START_NAMESPACE
  912. // ----------------------------------------------------------------------
  913. // U T I L F U N C T I O N S
  914. // ----------------------------------------------------------------------
  915. template <class E>
  916. inline void throw_exception(const E& exception)
  917. {
  918. #if !defined(SPP_NO_EXCEPTIONS)
  919. throw exception;
  920. #else
  921. assert(0);
  922. abort();
  923. #endif
  924. }
  925. // ----------------------------------------------------------------------
  926. // M U T A B L E P A I R H A C K
  927. // turn mutable std::pair<K, V> into correct value_type std::pair<const K, V>
  928. // ----------------------------------------------------------------------
  929. template <class T>
  930. struct cvt
  931. {
  932. typedef T type;
  933. };
  934. template <class K, class V>
  935. struct cvt<std::pair<K, V> >
  936. {
  937. typedef std::pair<const K, V> type;
  938. };
  939. template <class K, class V>
  940. struct cvt<const std::pair<K, V> >
  941. {
  942. typedef const std::pair<const K, V> type;
  943. };
  944. // ----------------------------------------------------------------------
  945. // M O V E I T E R A T O R
  946. // ----------------------------------------------------------------------
  947. #ifdef SPP_NO_CXX11_RVALUE_REFERENCES
  948. #define MK_MOVE_IT(p) (p)
  949. #else
  950. #define MK_MOVE_IT(p) std::make_move_iterator(p)
  951. #endif
  952. // ----------------------------------------------------------------------
  953. // A L L O C A T O R S T U F F
  954. // ----------------------------------------------------------------------
  955. template<class T>
  956. class libc_allocator_with_realloc
  957. {
  958. public:
  959. typedef T value_type;
  960. typedef size_t size_type;
  961. typedef ptrdiff_t difference_type;
  962. typedef T* pointer;
  963. typedef const T* const_pointer;
  964. typedef T& reference;
  965. typedef const T& const_reference;
  966. libc_allocator_with_realloc() {}
  967. libc_allocator_with_realloc(const libc_allocator_with_realloc& /*unused*/) {}
  968. ~libc_allocator_with_realloc() {}
  969. pointer address(reference r) const { return &r; }
  970. const_pointer address(const_reference r) const { return &r; }
  971. pointer allocate(size_type n, const_pointer /*unused*/= 0)
  972. {
  973. return static_cast<pointer>(malloc(n * sizeof(value_type)));
  974. }
  975. void deallocate(pointer p, size_type /*unused*/)
  976. {
  977. free(p);
  978. }
  979. pointer reallocate(pointer p, size_type n)
  980. {
  981. return static_cast<pointer>(realloc(p, n * sizeof(value_type)));
  982. }
  983. size_type max_size() const
  984. {
  985. return static_cast<size_type>(-1) / sizeof(value_type);
  986. }
  987. void construct(pointer p, const value_type& val)
  988. {
  989. new(p) value_type(val);
  990. }
  991. void destroy(pointer p) { p->~value_type(); }
  992. template <class U>
  993. explicit libc_allocator_with_realloc(const libc_allocator_with_realloc<U>& /*unused*/) {}
  994. template<class U>
  995. struct rebind
  996. {
  997. typedef libc_allocator_with_realloc<U> other;
  998. };
  999. };
  1000. // ----------------------------------------------------------------------
  1001. // libc_allocator_with_realloc<void> specialization.
  1002. // ----------------------------------------------------------------------
  1003. template<>
  1004. class libc_allocator_with_realloc<void>
  1005. {
  1006. public:
  1007. typedef void value_type;
  1008. typedef size_t size_type;
  1009. typedef ptrdiff_t difference_type;
  1010. typedef void* pointer;
  1011. typedef const void* const_pointer;
  1012. template<class U>
  1013. struct rebind
  1014. {
  1015. typedef libc_allocator_with_realloc<U> other;
  1016. };
  1017. };
  1018. template<class T>
  1019. inline bool operator==(const libc_allocator_with_realloc<T>& /*unused*/,
  1020. const libc_allocator_with_realloc<T>& /*unused*/)
  1021. {
  1022. return true;
  1023. }
  1024. template<class T>
  1025. inline bool operator!=(const libc_allocator_with_realloc<T>& /*unused*/,
  1026. const libc_allocator_with_realloc<T>& /*unused*/)
  1027. {
  1028. return false;
  1029. }
  1030. // ----------------------------------------------------------------------
  1031. // I N T E R N A L S T U F F
  1032. // ----------------------------------------------------------------------
  1033. #ifdef SPP_NO_CXX11_STATIC_ASSERT
  1034. template <bool> struct SppCompileAssert { };
  1035. #define SPP_COMPILE_ASSERT(expr, msg) \
  1036. SPP_ATTRIBUTE_UNUSED typedef SppCompileAssert<(bool(expr))> spp_bogus_[bool(expr) ? 1 : -1]
  1037. #else
  1038. #define SPP_COMPILE_ASSERT static_assert
  1039. #endif
  1040. namespace sparsehash_internal
  1041. {
  1042. // Adaptor methods for reading/writing data from an INPUT or OUPTUT
  1043. // variable passed to serialize() or unserialize(). For now we
  1044. // have implemented INPUT/OUTPUT for FILE*, istream*/ostream* (note
  1045. // they are pointers, unlike typical use), or else a pointer to
  1046. // something that supports a Read()/Write() method.
  1047. //
  1048. // For technical reasons, we implement read_data/write_data in two
  1049. // stages. The actual work is done in *_data_internal, which takes
  1050. // the stream argument twice: once as a template type, and once with
  1051. // normal type information. (We only use the second version.) We do
  1052. // this because of how C++ picks what function overload to use. If we
  1053. // implemented this the naive way:
  1054. // bool read_data(istream* is, const void* data, size_t length);
  1055. // template<typename T> read_data(T* fp, const void* data, size_t length);
  1056. // C++ would prefer the second version for every stream type except
  1057. // istream. However, we want C++ to prefer the first version for
  1058. // streams that are *subclasses* of istream, such as istringstream.
  1059. // This is not possible given the way template types are resolved. So
  1060. // we split the stream argument in two, one of which is templated and
  1061. // one of which is not. The specialized functions (like the istream
  1062. // version above) ignore the template arg and use the second, 'type'
  1063. // arg, getting subclass matching as normal. The 'catch-all'
  1064. // functions (the second version above) use the template arg to deduce
  1065. // the type, and use a second, void* arg to achieve the desired
  1066. // 'catch-all' semantics.
  1067. // ----- low-level I/O for FILE* ----
  1068. template<typename Ignored>
  1069. inline bool read_data_internal(Ignored* /*unused*/, FILE* fp,
  1070. void* data, size_t length)
  1071. {
  1072. return fread(data, length, 1, fp) == 1;
  1073. }
  1074. template<typename Ignored>
  1075. inline bool write_data_internal(Ignored* /*unused*/, FILE* fp,
  1076. const void* data, size_t length)
  1077. {
  1078. return fwrite(data, length, 1, fp) == 1;
  1079. }
  1080. // ----- low-level I/O for iostream ----
  1081. // We want the caller to be responsible for #including <iostream>, not
  1082. // us, because iostream is a big header! According to the standard,
  1083. // it's only legal to delay the instantiation the way we want to if
  1084. // the istream/ostream is a template type. So we jump through hoops.
  1085. template<typename ISTREAM>
  1086. inline bool read_data_internal_for_istream(ISTREAM* fp,
  1087. void* data, size_t length)
  1088. {
  1089. return fp->read(reinterpret_cast<char*>(data),
  1090. static_cast<std::streamsize>(length)).good();
  1091. }
  1092. template<typename Ignored>
  1093. inline bool read_data_internal(Ignored* /*unused*/, std::istream* fp,
  1094. void* data, size_t length)
  1095. {
  1096. return read_data_internal_for_istream(fp, data, length);
  1097. }
  1098. template<typename OSTREAM>
  1099. inline bool write_data_internal_for_ostream(OSTREAM* fp,
  1100. const void* data, size_t length)
  1101. {
  1102. return fp->write(reinterpret_cast<const char*>(data),
  1103. static_cast<std::streamsize>(length)).good();
  1104. }
  1105. template<typename Ignored>
  1106. inline bool write_data_internal(Ignored* /*unused*/, std::ostream* fp,
  1107. const void* data, size_t length)
  1108. {
  1109. return write_data_internal_for_ostream(fp, data, length);
  1110. }
  1111. // ----- low-level I/O for custom streams ----
  1112. // The INPUT type needs to support a Read() method that takes a
  1113. // buffer and a length and returns the number of bytes read.
  1114. template <typename INPUT>
  1115. inline bool read_data_internal(INPUT* fp, void* /*unused*/,
  1116. void* data, size_t length)
  1117. {
  1118. return static_cast<size_t>(fp->Read(data, length)) == length;
  1119. }
  1120. // The OUTPUT type needs to support a Write() operation that takes
  1121. // a buffer and a length and returns the number of bytes written.
  1122. template <typename OUTPUT>
  1123. inline bool write_data_internal(OUTPUT* fp, void* /*unused*/,
  1124. const void* data, size_t length)
  1125. {
  1126. return static_cast<size_t>(fp->Write(data, length)) == length;
  1127. }
  1128. // ----- low-level I/O: the public API ----
  1129. template <typename INPUT>
  1130. inline bool read_data(INPUT* fp, void* data, size_t length)
  1131. {
  1132. return read_data_internal(fp, fp, data, length);
  1133. }
  1134. template <typename OUTPUT>
  1135. inline bool write_data(OUTPUT* fp, const void* data, size_t length)
  1136. {
  1137. return write_data_internal(fp, fp, data, length);
  1138. }
  1139. // Uses read_data() and write_data() to read/write an integer.
  1140. // length is the number of bytes to read/write (which may differ
  1141. // from sizeof(IntType), allowing us to save on a 32-bit system
  1142. // and load on a 64-bit system). Excess bytes are taken to be 0.
  1143. // INPUT and OUTPUT must match legal inputs to read/write_data (above).
  1144. // --------------------------------------------------------------------
  1145. template <typename INPUT, typename IntType>
  1146. bool read_bigendian_number(INPUT* fp, IntType* value, size_t length)
  1147. {
  1148. *value = 0;
  1149. unsigned char byte;
  1150. // We require IntType to be unsigned or else the shifting gets all screwy.
  1151. SPP_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0), "serializing_int_requires_an_unsigned_type");
  1152. for (size_t i = 0; i < length; ++i)
  1153. {
  1154. if (!read_data(fp, &byte, sizeof(byte)))
  1155. return false;
  1156. *value |= static_cast<IntType>(byte) << ((length - 1 - i) * 8);
  1157. }
  1158. return true;
  1159. }
  1160. template <typename OUTPUT, typename IntType>
  1161. bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length)
  1162. {
  1163. unsigned char byte;
  1164. // We require IntType to be unsigned or else the shifting gets all screwy.
  1165. SPP_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0), "serializing_int_requires_an_unsigned_type");
  1166. for (size_t i = 0; i < length; ++i)
  1167. {
  1168. byte = (sizeof(value) <= length-1 - i)
  1169. ? static_cast<unsigned char>(0) : static_cast<unsigned char>((value >> ((length-1 - i) * 8)) & 255);
  1170. if (!write_data(fp, &byte, sizeof(byte))) return false;
  1171. }
  1172. return true;
  1173. }
  1174. // If your keys and values are simple enough, you can pass this
  1175. // serializer to serialize()/unserialize(). "Simple enough" means
  1176. // value_type is a POD type that contains no pointers. Note,
  1177. // however, we don't try to normalize endianness.
  1178. // This is the type used for NopointerSerializer.
  1179. // ---------------------------------------------------------------
  1180. template <typename value_type> struct pod_serializer
  1181. {
  1182. template <typename INPUT>
  1183. bool operator()(INPUT* fp, value_type* value) const
  1184. {
  1185. return read_data(fp, value, sizeof(*value));
  1186. }
  1187. template <typename OUTPUT>
  1188. bool operator()(OUTPUT* fp, const value_type& value) const
  1189. {
  1190. return write_data(fp, &value, sizeof(value));
  1191. }
  1192. };
  1193. // Settings contains parameters for growing and shrinking the table.
  1194. // It also packages zero-size functor (ie. hasher).
  1195. //
  1196. // It does some munging of the hash value in cases where we think
  1197. // (fear) the original hash function might not be very good. In
  1198. // particular, the default hash of pointers is the identity hash,
  1199. // so probably all the low bits are 0. We identify when we think
  1200. // we're hashing a pointer, and chop off the low bits. Note this
  1201. // isn't perfect: even when the key is a pointer, we can't tell
  1202. // for sure that the hash is the identity hash. If it's not, this
  1203. // is needless work (and possibly, though not likely, harmful).
  1204. // ---------------------------------------------------------------
  1205. template<typename Key, typename HashFunc,
  1206. typename SizeType, int HT_MIN_BUCKETS>
  1207. class sh_hashtable_settings : public HashFunc
  1208. {
  1209. private:
  1210. template <class T, int sz> struct Mixer
  1211. {
  1212. inline T operator()(T h) const;
  1213. };
  1214. template <class T> struct Mixer<T, 4>
  1215. {
  1216. inline T operator()(T h) const
  1217. {
  1218. return h + (h >> 7) + (h >> 13) + (h >> 23);
  1219. }
  1220. };
  1221. template <class T> struct Mixer<T, 8>
  1222. {
  1223. inline T operator()(T h) const
  1224. {
  1225. return h + (h >> 7) + (h >> 13) + (h >> 23) + (h >> 32);
  1226. }
  1227. };
  1228. public:
  1229. typedef Key key_type;
  1230. typedef HashFunc hasher;
  1231. typedef SizeType size_type;
  1232. public:
  1233. sh_hashtable_settings(const hasher& hf,
  1234. const float ht_occupancy_flt,
  1235. const float ht_empty_flt)
  1236. : hasher(hf),
  1237. enlarge_threshold_(0),
  1238. shrink_threshold_(0),
  1239. consider_shrink_(false),
  1240. num_ht_copies_(0)
  1241. {
  1242. set_enlarge_factor(ht_occupancy_flt);
  1243. set_shrink_factor(ht_empty_flt);
  1244. }
  1245. size_t hash(const key_type& v) const
  1246. {
  1247. size_t h = hasher::operator()(v);
  1248. Mixer<size_t, sizeof(size_t)> mixer;
  1249. return mixer(h);
  1250. }
  1251. float enlarge_factor() const { return enlarge_factor_; }
  1252. void set_enlarge_factor(float f) { enlarge_factor_ = f; }
  1253. float shrink_factor() const { return shrink_factor_; }
  1254. void set_shrink_factor(float f) { shrink_factor_ = f; }
  1255. size_type enlarge_threshold() const { return enlarge_threshold_; }
  1256. void set_enlarge_threshold(size_type t) { enlarge_threshold_ = t; }
  1257. size_type shrink_threshold() const { return shrink_threshold_; }
  1258. void set_shrink_threshold(size_type t) { shrink_threshold_ = t; }
  1259. size_type enlarge_size(size_type x) const { return static_cast<size_type>(x * enlarge_factor_); }
  1260. size_type shrink_size(size_type x) const { return static_cast<size_type>(x * shrink_factor_); }
  1261. bool consider_shrink() const { return consider_shrink_; }
  1262. void set_consider_shrink(bool t) { consider_shrink_ = t; }
  1263. unsigned int num_ht_copies() const { return num_ht_copies_; }
  1264. void inc_num_ht_copies() { ++num_ht_copies_; }
  1265. // Reset the enlarge and shrink thresholds
  1266. void reset_thresholds(size_type num_buckets)
  1267. {
  1268. set_enlarge_threshold(enlarge_size(num_buckets));
  1269. set_shrink_threshold(shrink_size(num_buckets));
  1270. // whatever caused us to reset already considered
  1271. set_consider_shrink(false);
  1272. }
  1273. // Caller is resposible for calling reset_threshold right after
  1274. // set_resizing_parameters.
  1275. // ------------------------------------------------------------
  1276. void set_resizing_parameters(float shrink, float grow)
  1277. {
  1278. assert(shrink >= 0.0);
  1279. assert(grow <= 1.0);
  1280. if (shrink > grow/2.0f)
  1281. shrink = grow / 2.0f; // otherwise we thrash hashtable size
  1282. set_shrink_factor(shrink);
  1283. set_enlarge_factor(grow);
  1284. }
  1285. // This is the smallest size a hashtable can be without being too crowded
  1286. // If you like, you can give a min #buckets as well as a min #elts
  1287. // ----------------------------------------------------------------------
  1288. size_type min_buckets(size_type num_elts, size_type min_buckets_wanted)
  1289. {
  1290. float enlarge = enlarge_factor();
  1291. size_type sz = HT_MIN_BUCKETS; // min buckets allowed
  1292. while (sz < min_buckets_wanted ||
  1293. num_elts >= static_cast<size_type>(sz * enlarge))
  1294. {
  1295. // This just prevents overflowing size_type, since sz can exceed
  1296. // max_size() here.
  1297. // -------------------------------------------------------------
  1298. if (static_cast<size_type>(sz * 2) < sz)
  1299. throw_exception(std::length_error("resize overflow")); // protect against overflow
  1300. sz *= 2;
  1301. }
  1302. return sz;
  1303. }
  1304. private:
  1305. size_type enlarge_threshold_; // table.size() * enlarge_factor
  1306. size_type shrink_threshold_; // table.size() * shrink_factor
  1307. float enlarge_factor_; // how full before resize
  1308. float shrink_factor_; // how empty before resize
  1309. bool consider_shrink_; // if we should try to shrink before next insert
  1310. unsigned int num_ht_copies_; // num_ht_copies is a counter incremented every Copy/Move
  1311. };
  1312. } // namespace sparsehash_internal
  1313. #undef SPP_COMPILE_ASSERT
  1314. // ----------------------------------------------------------------------
  1315. // S P A R S E T A B L E
  1316. // ----------------------------------------------------------------------
  1317. //
  1318. // A sparsetable is a random container that implements a sparse array,
  1319. // that is, an array that uses very little memory to store unassigned
  1320. // indices (in this case, between 1-2 bits per unassigned index). For
  1321. // instance, if you allocate an array of size 5 and assign a[2] = <big
  1322. // struct>, then a[2] will take up a lot of memory but a[0], a[1],
  1323. // a[3], and a[4] will not. Array elements that have a value are
  1324. // called "assigned". Array elements that have no value yet, or have
  1325. // had their value cleared using erase() or clear(), are called
  1326. // "unassigned".
  1327. //
  1328. // Unassigned values seem to have the default value of T (see below).
  1329. // Nevertheless, there is a difference between an unassigned index and
  1330. // one explicitly assigned the value of T(). The latter is considered
  1331. // assigned.
  1332. //
  1333. // Access to an array element is constant time, as is insertion and
  1334. // deletion. Insertion and deletion may be fairly slow, however:
  1335. // because of this container's memory economy, each insert and delete
  1336. // causes a memory reallocation.
  1337. //
  1338. // NOTE: You should not test(), get(), or set() any index that is
  1339. // greater than sparsetable.size(). If you need to do that, call
  1340. // resize() first.
  1341. //
  1342. // --- Template parameters
  1343. // PARAMETER DESCRIPTION DEFAULT
  1344. // T The value of the array: the type of --
  1345. // object that is stored in the array.
  1346. //
  1347. // Alloc: Allocator to use to allocate memory. libc_allocator_with_realloc
  1348. //
  1349. // --- Model of
  1350. // Random Access Container
  1351. //
  1352. // --- Type requirements
  1353. // T must be Copy Constructible. It need not be Assignable.
  1354. //
  1355. // --- Public base classes
  1356. // None.
  1357. //
  1358. // --- Members
  1359. //
  1360. // [*] All iterators are const in a sparsetable (though nonempty_iterators
  1361. // may not be). Use get() and set() to assign values, not iterators.
  1362. //
  1363. // [+] iterators are random-access iterators. nonempty_iterators are
  1364. // bidirectional iterators.
  1365. // [*] If you shrink a sparsetable using resize(), assigned elements
  1366. // past the end of the table are removed using erase(). If you grow
  1367. // a sparsetable, new unassigned indices are created.
  1368. //
  1369. // [+] Note that operator[] returns a const reference. You must use
  1370. // set() to change the value of a table element.
  1371. //
  1372. // [!] Unassignment also calls the destructor.
  1373. //
  1374. // Iterators are invalidated whenever an item is inserted or
  1375. // deleted (ie set() or erase() is used) or when the size of
  1376. // the table changes (ie resize() or clear() is used).
  1377. // ---------------------------------------------------------------------------
  1378. // type_traits we need
  1379. // ---------------------------------------------------------------------------
  1380. template<class T, T v>
  1381. struct integral_constant { static const T value = v; };
  1382. template <class T, T v> const T integral_constant<T, v>::value;
  1383. typedef integral_constant<bool, true> true_type;
  1384. typedef integral_constant<bool, false> false_type;
  1385. template<typename T, typename U> struct is_same : public false_type { };
  1386. template<typename T> struct is_same<T, T> : public true_type { };
  1387. template<typename T> struct remove_const { typedef T type; };
  1388. template<typename T> struct remove_const<T const> { typedef T type; };
  1389. template<typename T> struct remove_volatile { typedef T type; };
  1390. template<typename T> struct remove_volatile<T volatile> { typedef T type; };
  1391. template<typename T> struct remove_cv {
  1392. typedef typename remove_const<typename remove_volatile<T>::type>::type type;
  1393. };
  1394. // ---------------- is_integral ----------------------------------------
  1395. template <class T> struct is_integral;
  1396. template <class T> struct is_integral : false_type { };
  1397. template<> struct is_integral<bool> : true_type { };
  1398. template<> struct is_integral<char> : true_type { };
  1399. template<> struct is_integral<unsigned char> : true_type { };
  1400. template<> struct is_integral<signed char> : true_type { };
  1401. template<> struct is_integral<short> : true_type { };
  1402. template<> struct is_integral<unsigned short> : true_type { };
  1403. template<> struct is_integral<int> : true_type { };
  1404. template<> struct is_integral<unsigned int> : true_type { };
  1405. template<> struct is_integral<long> : true_type { };
  1406. template<> struct is_integral<unsigned long> : true_type { };
  1407. #ifdef SPP_HAS_LONG_LONG
  1408. template<> struct is_integral<long long> : true_type { };
  1409. template<> struct is_integral<unsigned long long> : true_type { };
  1410. #endif
  1411. template <class T> struct is_integral<const T> : is_integral<T> { };
  1412. template <class T> struct is_integral<volatile T> : is_integral<T> { };
  1413. template <class T> struct is_integral<const volatile T> : is_integral<T> { };
  1414. // ---------------- is_floating_point ----------------------------------------
  1415. template <class T> struct is_floating_point;
  1416. template <class T> struct is_floating_point : false_type { };
  1417. template<> struct is_floating_point<float> : true_type { };
  1418. template<> struct is_floating_point<double> : true_type { };
  1419. template<> struct is_floating_point<long double> : true_type { };
  1420. template <class T> struct is_floating_point<const T> : is_floating_point<T> { };
  1421. template <class T> struct is_floating_point<volatile T> : is_floating_point<T> { };
  1422. template <class T> struct is_floating_point<const volatile T> : is_floating_point<T> { };
  1423. // ---------------- is_pointer ----------------------------------------
  1424. template <class T> struct is_pointer;
  1425. template <class T> struct is_pointer : false_type { };
  1426. template <class T> struct is_pointer<T*> : true_type { };
  1427. template <class T> struct is_pointer<const T> : is_pointer<T> { };
  1428. template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
  1429. template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
  1430. // ---------------- is_reference ----------------------------------------
  1431. template <class T> struct is_reference;
  1432. template<typename T> struct is_reference : false_type {};
  1433. template<typename T> struct is_reference<T&> : true_type {};
  1434. // ---------------- is_relocatable ----------------------------------------
  1435. // relocatable values can be moved around in memory using memcpy and remain
  1436. // correct. Most types are relocatable, an example of a type who is not would
  1437. // be a struct which contains a pointer to a buffer inside itself - this is the
  1438. // case for std::string in gcc 5.
  1439. // ------------------------------------------------------------------------
  1440. template <class T> struct is_relocatable;
  1441. template <class T> struct is_relocatable :
  1442. integral_constant<bool, (is_integral<T>::value || is_floating_point<T>::value)>
  1443. { };
  1444. template<int S, int H> struct is_relocatable<HashObject<S, H> > : true_type { };
  1445. template <class T> struct is_relocatable<const T> : is_relocatable<T> { };
  1446. template <class T> struct is_relocatable<volatile T> : is_relocatable<T> { };
  1447. template <class T> struct is_relocatable<const volatile T> : is_relocatable<T> { };
  1448. template <class A, int N> struct is_relocatable<A[N]> : is_relocatable<A> { };
  1449. template <class T, class U> struct is_relocatable<std::pair<T, U> > :
  1450. integral_constant<bool, (is_relocatable<T>::value && is_relocatable<U>::value)>
  1451. { };
  1452. // ---------------------------------------------------------------------------
  1453. // Our iterator as simple as iterators can be: basically it's just
  1454. // the index into our table. Dereference, the only complicated
  1455. // thing, we punt to the table class. This just goes to show how
  1456. // much machinery STL requires to do even the most trivial tasks.
  1457. //
  1458. // A NOTE ON ASSIGNING:
  1459. // A sparse table does not actually allocate memory for entries
  1460. // that are not filled. Because of this, it becomes complicated
  1461. // to have a non-const iterator: we don't know, if the iterator points
  1462. // to a not-filled bucket, whether you plan to fill it with something
  1463. // or whether you plan to read its value (in which case you'll get
  1464. // the default bucket value). Therefore, while we can define const
  1465. // operations in a pretty 'normal' way, for non-const operations, we
  1466. // define something that returns a helper object with operator= and
  1467. // operator& that allocate a bucket lazily. We use this for table[]
  1468. // and also for regular table iterators.
  1469. // ---------------------------------------------------------------------------
  1470. // ---------------------------------------------------------------------------
  1471. template <class tabletype>
  1472. class table_element_adaptor
  1473. {
  1474. public:
  1475. typedef typename tabletype::value_type value_type;
  1476. typedef typename tabletype::size_type size_type;
  1477. typedef typename tabletype::reference reference;
  1478. typedef typename tabletype::pointer pointer;
  1479. table_element_adaptor(tabletype *tbl, size_type p) :
  1480. table(tbl), pos(p)
  1481. { }
  1482. table_element_adaptor& operator=(const value_type &val)
  1483. {
  1484. table->set(pos, val, false);
  1485. return *this;
  1486. }
  1487. operator value_type() { return table->get(pos); } // we look like a value
  1488. pointer operator& () { return &table->mutating_get(pos); }
  1489. private:
  1490. tabletype* table;
  1491. size_type pos;
  1492. };
  1493. // Our iterator as simple as iterators can be: basically it's just
  1494. // the index into our table. Dereference, the only complicated
  1495. // thing, we punt to the table class. This just goes to show how
  1496. // much machinery STL requires to do even the most trivial tasks.
  1497. //
  1498. // By templatizing over tabletype, we have one iterator type which
  1499. // we can use for both sparsetables and sparsebins. In fact it
  1500. // works on any class that allows size() and operator[] (eg vector),
  1501. // as long as it does the standard STL typedefs too (eg value_type).
  1502. // ---------------------------------------------------------------------------
  1503. // ---------------------------------------------------------------------------
  1504. template <class tabletype>
  1505. class table_iterator
  1506. {
  1507. public:
  1508. typedef table_iterator iterator;
  1509. typedef std::random_access_iterator_tag iterator_category;
  1510. typedef typename tabletype::value_type value_type;
  1511. typedef typename tabletype::difference_type difference_type;
  1512. typedef typename tabletype::size_type size_type;
  1513. typedef table_element_adaptor<tabletype> reference;
  1514. typedef table_element_adaptor<tabletype>* pointer;
  1515. explicit table_iterator(tabletype *tbl = 0, size_type p = 0) :
  1516. table(tbl), pos(p)
  1517. { }
  1518. // The main thing our iterator does is dereference. If the table entry
  1519. // we point to is empty, we return the default value type.
  1520. // This is the big different function from the const iterator.
  1521. reference operator*()
  1522. {
  1523. return table_element_adaptor<tabletype>(table, pos);
  1524. }
  1525. pointer operator->() { return &(operator*()); }
  1526. // Helper function to assert things are ok; eg pos is still in range
  1527. void check() const
  1528. {
  1529. assert(table);
  1530. assert(pos <= table->size());
  1531. }
  1532. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1533. // do bounds checking, since STL doesn't consider that its job. :-)
  1534. iterator& operator+=(size_type t) { pos += t; check(); return *this; }
  1535. iterator& operator-=(size_type t) { pos -= t; check(); return *this; }
  1536. iterator& operator++() { ++pos; check(); return *this; }
  1537. iterator& operator--() { --pos; check(); return *this; }
  1538. iterator operator++(int)
  1539. {
  1540. iterator tmp(*this); // for x++
  1541. ++pos; check(); return tmp;
  1542. }
  1543. iterator operator--(int)
  1544. {
  1545. iterator tmp(*this); // for x--
  1546. --pos; check(); return tmp;
  1547. }
  1548. iterator operator+(difference_type i) const
  1549. {
  1550. iterator tmp(*this);
  1551. tmp += i; return tmp;
  1552. }
  1553. iterator operator-(difference_type i) const
  1554. {
  1555. iterator tmp(*this);
  1556. tmp -= i; return tmp;
  1557. }
  1558. difference_type operator-(iterator it) const
  1559. { // for "x = it2 - it"
  1560. assert(table == it.table);
  1561. return pos - it.pos;
  1562. }
  1563. reference operator[](difference_type n) const
  1564. {
  1565. return *(*this + n); // simple though not totally efficient
  1566. }
  1567. // Comparisons.
  1568. bool operator==(const iterator& it) const
  1569. {
  1570. return table == it.table && pos == it.pos;
  1571. }
  1572. bool operator<(const iterator& it) const
  1573. {
  1574. assert(table == it.table); // life is bad bad bad otherwise
  1575. return pos < it.pos;
  1576. }
  1577. bool operator!=(const iterator& it) const { return !(*this == it); }
  1578. bool operator<=(const iterator& it) const { return !(it < *this); }
  1579. bool operator>(const iterator& it) const { return it < *this; }
  1580. bool operator>=(const iterator& it) const { return !(*this < it); }
  1581. // Here's the info we actually need to be an iterator
  1582. tabletype *table; // so we can dereference and bounds-check
  1583. size_type pos; // index into the table
  1584. };
  1585. // ---------------------------------------------------------------------------
  1586. // ---------------------------------------------------------------------------
  1587. template <class tabletype>
  1588. class const_table_iterator
  1589. {
  1590. public:
  1591. typedef table_iterator<tabletype> iterator;
  1592. typedef const_table_iterator const_iterator;
  1593. typedef std::random_access_iterator_tag iterator_category;
  1594. typedef typename tabletype::value_type value_type;
  1595. typedef typename tabletype::difference_type difference_type;
  1596. typedef typename tabletype::size_type size_type;
  1597. typedef typename tabletype::const_reference reference; // we're const-only
  1598. typedef typename tabletype::const_pointer pointer;
  1599. // The "real" constructor
  1600. const_table_iterator(const tabletype *tbl, size_type p)
  1601. : table(tbl), pos(p) { }
  1602. // The default constructor, used when I define vars of type table::iterator
  1603. const_table_iterator() : table(NULL), pos(0) { }
  1604. // The copy constructor, for when I say table::iterator foo = tbl.begin()
  1605. // Also converts normal iterators to const iterators // not explicit on purpose
  1606. const_table_iterator(const iterator &from)
  1607. : table(from.table), pos(from.pos) { }
  1608. // The default destructor is fine; we don't define one
  1609. // The default operator= is fine; we don't define one
  1610. // The main thing our iterator does is dereference. If the table entry
  1611. // we point to is empty, we return the default value type.
  1612. reference operator*() const { return (*table)[pos]; }
  1613. pointer operator->() const { return &(operator*()); }
  1614. // Helper function to assert things are ok; eg pos is still in range
  1615. void check() const
  1616. {
  1617. assert(table);
  1618. assert(pos <= table->size());
  1619. }
  1620. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1621. // do bounds checking, since STL doesn't consider that its job. :-)
  1622. const_iterator& operator+=(size_type t) { pos += t; check(); return *this; }
  1623. const_iterator& operator-=(size_type t) { pos -= t; check(); return *this; }
  1624. const_iterator& operator++() { ++pos; check(); return *this; }
  1625. const_iterator& operator--() { --pos; check(); return *this; }
  1626. const_iterator operator++(int) { const_iterator tmp(*this); // for x++
  1627. ++pos; check(); return tmp; }
  1628. const_iterator operator--(int) { const_iterator tmp(*this); // for x--
  1629. --pos; check(); return tmp; }
  1630. const_iterator operator+(difference_type i) const
  1631. {
  1632. const_iterator tmp(*this);
  1633. tmp += i;
  1634. return tmp;
  1635. }
  1636. const_iterator operator-(difference_type i) const
  1637. {
  1638. const_iterator tmp(*this);
  1639. tmp -= i;
  1640. return tmp;
  1641. }
  1642. difference_type operator-(const_iterator it) const
  1643. { // for "x = it2 - it"
  1644. assert(table == it.table);
  1645. return pos - it.pos;
  1646. }
  1647. reference operator[](difference_type n) const
  1648. {
  1649. return *(*this + n); // simple though not totally efficient
  1650. }
  1651. // Comparisons.
  1652. bool operator==(const const_iterator& it) const
  1653. {
  1654. return table == it.table && pos == it.pos;
  1655. }
  1656. bool operator<(const const_iterator& it) const
  1657. {
  1658. assert(table == it.table); // life is bad bad bad otherwise
  1659. return pos < it.pos;
  1660. }
  1661. bool operator!=(const const_iterator& it) const { return !(*this == it); }
  1662. bool operator<=(const const_iterator& it) const { return !(it < *this); }
  1663. bool operator>(const const_iterator& it) const { return it < *this; }
  1664. bool operator>=(const const_iterator& it) const { return !(*this < it); }
  1665. // Here's the info we actually need to be an iterator
  1666. const tabletype *table; // so we can dereference and bounds-check
  1667. size_type pos; // index into the table
  1668. };
  1669. // ---------------------------------------------------------------------------
  1670. // This is a 2-D iterator. You specify a begin and end over a list
  1671. // of *containers*. We iterate over each container by iterating over
  1672. // it. It's actually simple:
  1673. // VECTOR.begin() VECTOR[0].begin() --------> VECTOR[0].end() ---,
  1674. // | ________________________________________________/
  1675. // | \_> VECTOR[1].begin() --------> VECTOR[1].end() -,
  1676. // | ___________________________________________________/
  1677. // v \_> ......
  1678. // VECTOR.end()
  1679. //
  1680. // It's impossible to do random access on one of these things in constant
  1681. // time, so it's just a bidirectional iterator.
  1682. //
  1683. // Unfortunately, because we need to use this for a non-empty iterator,
  1684. // we use ne_begin() and ne_end() instead of begin() and end()
  1685. // (though only going across, not down).
  1686. // ---------------------------------------------------------------------------
  1687. // ---------------------------------------------------------------------------
  1688. // ---------------------------------------------------------------------------
  1689. template <class T, class row_it, class col_it, class iter_type>
  1690. class Two_d_iterator : public std::iterator<iter_type, T>
  1691. {
  1692. public:
  1693. typedef Two_d_iterator iterator;
  1694. // T can be std::pair<K, V>, but we need to return std::pair<const K, V>
  1695. // ---------------------------------------------------------------------
  1696. typedef typename spp_::cvt<T>::type value_type;
  1697. typedef value_type& reference;
  1698. typedef value_type* pointer;
  1699. explicit Two_d_iterator(row_it curr) : row_current(curr), col_current(0)
  1700. {
  1701. if (row_current && !row_current->is_marked())
  1702. {
  1703. col_current = row_current->ne_begin();
  1704. advance_past_end(); // in case cur->begin() == cur->end()
  1705. }
  1706. }
  1707. explicit Two_d_iterator(row_it curr, col_it col) : row_current(curr), col_current(col)
  1708. {
  1709. assert(col);
  1710. }
  1711. // The default constructor
  1712. Two_d_iterator() : row_current(0), col_current(0) { }
  1713. // Need this explicitly so we can convert normal iterators <=> const iterators
  1714. // not explicit on purpose
  1715. // ---------------------------------------------------------------------------
  1716. template <class T2, class row_it2, class col_it2, class iter_type2>
  1717. Two_d_iterator(const Two_d_iterator<T2, row_it2, col_it2, iter_type2>& it) :
  1718. row_current (*(row_it *)&it.row_current),
  1719. col_current (*(col_it *)&it.col_current)
  1720. { }
  1721. // The default destructor is fine; we don't define one
  1722. // The default operator= is fine; we don't define one
  1723. reference operator*() const { return *(col_current); }
  1724. pointer operator->() const { return &(operator*()); }
  1725. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1726. // do bounds checking, since STL doesn't consider that its job. :-)
  1727. // NOTE: this is not amortized constant time! What do we do about it?
  1728. // ------------------------------------------------------------------
  1729. void advance_past_end()
  1730. {
  1731. // used when col_current points to end()
  1732. while (col_current == row_current->ne_end())
  1733. {
  1734. // end of current row
  1735. // ------------------
  1736. ++row_current; // go to beginning of next
  1737. if (!row_current->is_marked()) // col is irrelevant at end
  1738. col_current = row_current->ne_begin();
  1739. else
  1740. break; // don't go past row_end
  1741. }
  1742. }
  1743. friend size_t operator-(iterator l, iterator f)
  1744. {
  1745. if (f.row_current->is_marked())
  1746. return 0;
  1747. size_t diff(0);
  1748. while (f != l)
  1749. {
  1750. ++diff;
  1751. ++f;
  1752. }
  1753. return diff;
  1754. }
  1755. iterator& operator++()
  1756. {
  1757. // assert(!row_current->is_marked()); // how to ++ from there?
  1758. ++col_current;
  1759. advance_past_end(); // in case col_current is at end()
  1760. return *this;
  1761. }
  1762. iterator& operator--()
  1763. {
  1764. while (row_current->is_marked() ||
  1765. col_current == row_current->ne_begin())
  1766. {
  1767. --row_current;
  1768. col_current = row_current->ne_end(); // this is 1 too far
  1769. }
  1770. --col_current;
  1771. return *this;
  1772. }
  1773. iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; }
  1774. iterator operator--(int) { iterator tmp(*this); --*this; return tmp; }
  1775. // Comparisons.
  1776. bool operator==(const iterator& it) const
  1777. {
  1778. return (row_current == it.row_current &&
  1779. (!row_current || row_current->is_marked() || col_current == it.col_current));
  1780. }
  1781. bool operator!=(const iterator& it) const { return !(*this == it); }
  1782. // Here's the info we actually need to be an iterator
  1783. // These need to be public so we convert from iterator to const_iterator
  1784. // ---------------------------------------------------------------------
  1785. row_it row_current;
  1786. col_it col_current;
  1787. };
  1788. // ---------------------------------------------------------------------------
  1789. // ---------------------------------------------------------------------------
  1790. template <class T, class row_it, class col_it, class iter_type, class Alloc>
  1791. class Two_d_destructive_iterator : public Two_d_iterator<T, row_it, col_it, iter_type>
  1792. {
  1793. public:
  1794. typedef Two_d_destructive_iterator iterator;
  1795. Two_d_destructive_iterator(Alloc &alloc, row_it curr) :
  1796. _alloc(alloc)
  1797. {
  1798. this->row_current = curr;
  1799. this->col_current = 0;
  1800. if (this->row_current && !this->row_current->is_marked())
  1801. {
  1802. this->col_current = this->row_current->ne_begin();
  1803. advance_past_end(); // in case cur->begin() == cur->end()
  1804. }
  1805. }
  1806. // Arithmetic: we just do arithmetic on pos. We don't even need to
  1807. // do bounds checking, since STL doesn't consider that its job. :-)
  1808. // NOTE: this is not amortized constant time! What do we do about it?
  1809. // ------------------------------------------------------------------
  1810. void advance_past_end()
  1811. {
  1812. // used when col_current points to end()
  1813. while (this->col_current == this->row_current->ne_end())
  1814. {
  1815. this->row_current->clear(_alloc, true); // This is what differs from non-destructive iterators above
  1816. // end of current row
  1817. // ------------------
  1818. ++this->row_current; // go to beginning of next
  1819. if (!this->row_current->is_marked()) // col is irrelevant at end
  1820. this->col_current = this->row_current->ne_begin();
  1821. else
  1822. break; // don't go past row_end
  1823. }
  1824. }
  1825. iterator& operator++()
  1826. {
  1827. // assert(!this->row_current->is_marked()); // how to ++ from there?
  1828. ++this->col_current;
  1829. advance_past_end(); // in case col_current is at end()
  1830. return *this;
  1831. }
  1832. private:
  1833. Two_d_destructive_iterator& operator=(const Two_d_destructive_iterator &o);
  1834. Alloc &_alloc;
  1835. };
  1836. // ---------------------------------------------------------------------------
  1837. // ---------------------------------------------------------------------------
  1838. static const char spp_bits_in[256] = {
  1839. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
  1840. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1841. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1842. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1843. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1844. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1845. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1846. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1847. 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
  1848. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1849. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1850. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1851. 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
  1852. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1853. 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
  1854. 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
  1855. };
  1856. static inline uint32_t s_spp_popcount_default_lut(uint32_t i)
  1857. {
  1858. uint32_t res = static_cast<uint32_t>(spp_bits_in[i & 0xFF]);
  1859. res += static_cast<uint32_t>(spp_bits_in[(i >> 8) & 0xFF]);
  1860. res += static_cast<uint32_t>(spp_bits_in[(i >> 16) & 0xFF]);
  1861. res += static_cast<uint32_t>(spp_bits_in[i >> 24]);
  1862. return res;
  1863. }
  1864. static inline uint32_t s_spp_popcount_default_lut(uint64_t i)
  1865. {
  1866. uint32_t res = static_cast<uint32_t>(spp_bits_in[i & 0xFF]);
  1867. res += static_cast<uint32_t>(spp_bits_in[(i >> 8) & 0xFF]);
  1868. res += static_cast<uint32_t>(spp_bits_in[(i >> 16) & 0xFF]);
  1869. res += static_cast<uint32_t>(spp_bits_in[(i >> 24) & 0xFF]);
  1870. res += static_cast<uint32_t>(spp_bits_in[(i >> 32) & 0xFF]);
  1871. res += static_cast<uint32_t>(spp_bits_in[(i >> 40) & 0xFF]);
  1872. res += static_cast<uint32_t>(spp_bits_in[(i >> 48) & 0xFF]);
  1873. res += static_cast<uint32_t>(spp_bits_in[i >> 56]);
  1874. return res;
  1875. }
  1876. // faster than the lookup table (LUT)
  1877. // ----------------------------------
  1878. static inline uint32_t s_spp_popcount_default(uint32_t i)
  1879. {
  1880. i = i - ((i >> 1) & 0x55555555);
  1881. i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
  1882. return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
  1883. }
  1884. // faster than the lookup table (LUT)
  1885. // ----------------------------------
  1886. static inline uint32_t s_spp_popcount_default(uint64_t x)
  1887. {
  1888. const uint64_t m1 = uint64_t(0x5555555555555555); // binary: 0101...
  1889. const uint64_t m2 = uint64_t(0x3333333333333333); // binary: 00110011..
  1890. const uint64_t m4 = uint64_t(0x0f0f0f0f0f0f0f0f); // binary: 4 zeros, 4 ones ...
  1891. const uint64_t h01 = uint64_t(0x0101010101010101); // the sum of 256 to the power of 0,1,2,3...
  1892. x -= (x >> 1) & m1; // put count of each 2 bits into those 2 bits
  1893. x = (x & m2) + ((x >> 2) & m2); // put count of each 4 bits into those 4 bits
  1894. x = (x + (x >> 4)) & m4; // put count of each 8 bits into those 8 bits
  1895. return (x * h01)>>56; // returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24)+...
  1896. }
  1897. #if defined(SPP_POPCNT_CHECK)
  1898. static inline bool spp_popcount_check()
  1899. {
  1900. int cpuInfo[4] = { -1 };
  1901. spp_cpuid(cpuInfo, 1);
  1902. if (cpuInfo[2] & (1 << 23))
  1903. return true; // means SPP_POPCNT supported
  1904. return false;
  1905. }
  1906. #endif
  1907. #if defined(SPP_POPCNT_CHECK) && defined(SPP_POPCNT)
  1908. static inline uint32_t spp_popcount(uint32_t i)
  1909. {
  1910. static const bool s_ok = spp_popcount_check();
  1911. return s_ok ? SPP_POPCNT(i) : s_spp_popcount_default(i);
  1912. }
  1913. #else
  1914. static inline uint32_t spp_popcount(uint32_t i)
  1915. {
  1916. #if defined(SPP_POPCNT)
  1917. return static_cast<uint32_t>(SPP_POPCNT(i));
  1918. #else
  1919. return s_spp_popcount_default(i);
  1920. #endif
  1921. }
  1922. #endif
  1923. #if defined(SPP_POPCNT_CHECK) && defined(SPP_POPCNT64)
  1924. static inline uint32_t spp_popcount(uint64_t i)
  1925. {
  1926. static const bool s_ok = spp_popcount_check();
  1927. return s_ok ? (uint32_t)SPP_POPCNT64(i) : s_spp_popcount_default(i);
  1928. }
  1929. #else
  1930. static inline uint32_t spp_popcount(uint64_t i)
  1931. {
  1932. #if defined(SPP_POPCNT64)
  1933. return static_cast<uint32_t>(SPP_POPCNT64(i));
  1934. #elif 1
  1935. return s_spp_popcount_default(i);
  1936. #endif
  1937. }
  1938. #endif
  1939. // ---------------------------------------------------------------------------
  1940. // SPARSE-TABLE
  1941. // ------------
  1942. // The idea is that a table with (logically) t buckets is divided
  1943. // into t/M *groups* of M buckets each. (M is a constant, typically
  1944. // 32) Each group is stored sparsely.
  1945. // Thus, inserting into the table causes some array to grow, which is
  1946. // slow but still constant time. Lookup involves doing a
  1947. // logical-position-to-sparse-position lookup, which is also slow but
  1948. // constant time. The larger M is, the slower these operations are
  1949. // but the less overhead (slightly).
  1950. //
  1951. // To store the sparse array, we store a bitmap B, where B[i] = 1 iff
  1952. // bucket i is non-empty. Then to look up bucket i we really look up
  1953. // array[# of 1s before i in B]. This is constant time for fixed M.
  1954. //
  1955. // Terminology: the position of an item in the overall table (from
  1956. // 1 .. t) is called its "location." The logical position in a group
  1957. // (from 1 .. M) is called its "position." The actual location in
  1958. // the array (from 1 .. # of non-empty buckets in the group) is
  1959. // called its "offset."
  1960. // ---------------------------------------------------------------------------
  1961. template <class T, class Alloc>
  1962. class sparsegroup
  1963. {
  1964. public:
  1965. // Basic types
  1966. typedef typename spp::cvt<T>::type value_type;
  1967. typedef Alloc allocator_type;
  1968. typedef value_type& reference;
  1969. typedef const value_type& const_reference;
  1970. typedef value_type* pointer;
  1971. typedef const value_type* const_pointer;
  1972. typedef table_element_adaptor<sparsegroup<T, Alloc> > element_adaptor;
  1973. typedef uint8_t size_type; // max # of buckets
  1974. // These are our special iterators, that go over non-empty buckets in a
  1975. // group. These aren't const-only because you can change non-empty bcks.
  1976. // ---------------------------------------------------------------------
  1977. typedef pointer ne_iterator;
  1978. typedef const_pointer const_ne_iterator;
  1979. typedef std::reverse_iterator<ne_iterator> reverse_ne_iterator;
  1980. typedef std::reverse_iterator<const_ne_iterator> const_reverse_ne_iterator;
  1981. // We'll have versions for our special non-empty iterator too
  1982. // ----------------------------------------------------------
  1983. ne_iterator ne_begin() { return reinterpret_cast<pointer>(_group); }
  1984. const_ne_iterator ne_begin() const { return reinterpret_cast<pointer>(_group); }
  1985. const_ne_iterator ne_cbegin() const { return reinterpret_cast<pointer>(_group); }
  1986. ne_iterator ne_end() { return reinterpret_cast<pointer>(_group + _num_items()); }
  1987. const_ne_iterator ne_end() const { return reinterpret_cast<pointer>(_group + _num_items()); }
  1988. const_ne_iterator ne_cend() const { return reinterpret_cast<pointer>(_group + _num_items()); }
  1989. reverse_ne_iterator ne_rbegin() { return reverse_ne_iterator(ne_end()); }
  1990. const_reverse_ne_iterator ne_rbegin() const { return const_reverse_ne_iterator(ne_cend()); }
  1991. const_reverse_ne_iterator ne_crbegin() const { return const_reverse_ne_iterator(ne_cend()); }
  1992. reverse_ne_iterator ne_rend() { return reverse_ne_iterator(ne_begin()); }
  1993. const_reverse_ne_iterator ne_rend() const { return const_reverse_ne_iterator(ne_cbegin()); }
  1994. const_reverse_ne_iterator ne_crend() const { return const_reverse_ne_iterator(ne_cbegin()); }
  1995. // This gives us the "default" value to return for an empty bucket.
  1996. // We just use the default constructor on T, the template type
  1997. // ----------------------------------------------------------------
  1998. const_reference default_value() const
  1999. {
  2000. static value_type defaultval = value_type();
  2001. return defaultval;
  2002. }
  2003. private:
  2004. // T can be std::pair<K, V>, but we need to return std::pair<const K, V>
  2005. // ---------------------------------------------------------------------
  2006. typedef T mutable_value_type;
  2007. typedef mutable_value_type& mutable_reference;
  2008. typedef const mutable_value_type& const_mutable_reference;
  2009. typedef mutable_value_type* mutable_pointer;
  2010. typedef const mutable_value_type* const_mutable_pointer;
  2011. #define spp_mutable_ref(x) (*(reinterpret_cast<mutable_pointer>(&(x))))
  2012. #define spp_const_mutable_ref(x) (*(reinterpret_cast<const_mutable_pointer>(&(x))))
  2013. typedef typename Alloc::template rebind<T>::other value_alloc_type;
  2014. bool _bmtest(size_type i) const { return !!(_bitmap & (static_cast<group_bm_type>(1) << i)); }
  2015. void _bmset(size_type i) { _bitmap |= static_cast<group_bm_type>(1) << i; }
  2016. void _bmclear(size_type i) { _bitmap &= ~(static_cast<group_bm_type>(1) << i); }
  2017. bool _bme_test(size_type i) const { return !!(_bm_erased & (static_cast<group_bm_type>(1) << i)); }
  2018. void _bme_set(size_type i) { _bm_erased |= static_cast<group_bm_type>(1) << i; }
  2019. void _bme_clear(size_type i) { _bm_erased &= ~(static_cast<group_bm_type>(1) << i); }
  2020. bool _bmtest_strict(size_type i) const
  2021. { return !!((_bitmap | _bm_erased) & (static_cast<group_bm_type>(1) << i)); }
  2022. static uint32_t _sizing(uint32_t n)
  2023. {
  2024. #if !defined(SPP_ALLOC_SZ) || (SPP_ALLOC_SZ == 0)
  2025. // aggressive allocation first, then decreasing as sparsegroups fill up
  2026. // --------------------------------------------------------------------
  2027. static uint8_t s_alloc_batch_sz[SPP_GROUP_SIZE] = { 0 };
  2028. if (!s_alloc_batch_sz[0])
  2029. {
  2030. // 32 bit bitmap
  2031. // ........ .... .... .. .. .. .. . . . . . . . .
  2032. // 8 12 16 18 20 22 24 25 26 ... 32
  2033. // ------------------------------------------------------
  2034. uint8_t group_sz = SPP_GROUP_SIZE / 4;
  2035. uint8_t group_start_alloc = SPP_GROUP_SIZE / 8; //4;
  2036. uint8_t alloc_sz = group_start_alloc;
  2037. for (int i=0; i<4; ++i)
  2038. {
  2039. for (int j=0; j<group_sz; ++j)
  2040. {
  2041. if (j && j % group_start_alloc == 0)
  2042. alloc_sz += group_start_alloc;
  2043. s_alloc_batch_sz[i * group_sz + j] = alloc_sz;
  2044. }
  2045. if (group_start_alloc > 2)
  2046. group_start_alloc /= 2;
  2047. alloc_sz += group_start_alloc;
  2048. }
  2049. }
  2050. return n ? static_cast<uint32_t>(s_alloc_batch_sz[n-1]) : 0; // more aggressive alloc at the beginning
  2051. #elif (SPP_ALLOC_SZ == 1)
  2052. // use as little memory as possible - slowest insert/delete in table
  2053. // -----------------------------------------------------------------
  2054. return n;
  2055. #else
  2056. // decent compromise when SPP_ALLOC_SZ == 2
  2057. // ----------------------------------------
  2058. static size_type sz_minus_1 = SPP_ALLOC_SZ - 1;
  2059. return (n + sz_minus_1) & ~sz_minus_1;
  2060. #endif
  2061. }
  2062. mutable_pointer _allocate_group(Alloc &alloc, uint32_t n /* , bool tight = false */)
  2063. {
  2064. // ignore tight since we don't store num_alloc
  2065. // num_alloc = (uint8_t)(tight ? n : _sizing(n));
  2066. uint32_t num_alloc = (uint8_t)_sizing(n);
  2067. _set_num_alloc(num_alloc);
  2068. mutable_pointer retval = alloc.allocate(static_cast<size_type>(num_alloc));
  2069. if (retval == NULL)
  2070. {
  2071. // the allocator is supposed to throw an exception if the allocation fails.
  2072. fprintf(stderr, "sparsehash FATAL ERROR: failed to allocate %d groups\n", num_alloc);
  2073. exit(1);
  2074. }
  2075. return retval;
  2076. }
  2077. void _free_group(Alloc &alloc, uint32_t num_alloc)
  2078. {
  2079. if (_group)
  2080. {
  2081. uint32_t num_buckets = _num_items();
  2082. if (num_buckets)
  2083. {
  2084. mutable_pointer end_it = _group + num_buckets;
  2085. for (mutable_pointer p = _group; p != end_it; ++p)
  2086. p->~mutable_value_type();
  2087. }
  2088. alloc.deallocate(_group, (typename allocator_type::size_type)num_alloc);
  2089. _group = NULL;
  2090. }
  2091. }
  2092. // private because should not be called - no allocator!
  2093. sparsegroup &operator=(const sparsegroup& x);
  2094. static size_type _pos_to_offset(group_bm_type bm, size_type pos)
  2095. {
  2096. //return (size_type)((uint32_t)~((int32_t(-1) + pos) >> 31) & spp_popcount(bm << (SPP_GROUP_SIZE - pos)));
  2097. //return (size_type)(pos ? spp_popcount(bm << (SPP_GROUP_SIZE - pos)) : 0);
  2098. return static_cast<size_type>(spp_popcount(bm & ((static_cast<group_bm_type>(1) << pos) - 1)));
  2099. }
  2100. public:
  2101. // get_iter() in sparsetable needs it
  2102. size_type pos_to_offset(size_type pos) const
  2103. {
  2104. return _pos_to_offset(_bitmap, pos);
  2105. }
  2106. #ifdef _MSC_VER
  2107. #pragma warning(push)
  2108. #pragma warning(disable : 4146)
  2109. #endif
  2110. // Returns the (logical) position in the bm[] array, i, such that
  2111. // bm[i] is the offset-th set bit in the array. It is the inverse
  2112. // of pos_to_offset. get_pos() uses this function to find the index
  2113. // of an ne_iterator in the table. Bit-twiddling from
  2114. // http://hackersdelight.org/basics.pdf
  2115. // -----------------------------------------------------------------
  2116. static size_type offset_to_pos(group_bm_type bm, size_type offset)
  2117. {
  2118. for (; offset > 0; offset--)
  2119. bm &= (bm-1); // remove right-most set bit
  2120. // Clear all bits to the left of the rightmost bit (the &),
  2121. // and then clear the rightmost bit but set all bits to the
  2122. // right of it (the -1).
  2123. // --------------------------------------------------------
  2124. bm = (bm & -bm) - 1;
  2125. return static_cast<size_type>(spp_popcount(bm));
  2126. }
  2127. #ifdef _MSC_VER
  2128. #pragma warning(pop)
  2129. #endif
  2130. size_type offset_to_pos(size_type offset) const
  2131. {
  2132. return offset_to_pos(_bitmap, offset);
  2133. }
  2134. public:
  2135. // Constructors -- default and copy -- and destructor
  2136. explicit sparsegroup() :
  2137. _group(0), _bitmap(0), _bm_erased(0)
  2138. {
  2139. _set_num_items(0);
  2140. _set_num_alloc(0);
  2141. }
  2142. sparsegroup(const sparsegroup& x) :
  2143. _group(0), _bitmap(x._bitmap), _bm_erased(x._bm_erased)
  2144. {
  2145. _set_num_items(0);
  2146. _set_num_alloc(0);
  2147. assert(_group == 0); if (_group) exit(1);
  2148. }
  2149. sparsegroup(const sparsegroup& x, allocator_type& a) :
  2150. _group(0), _bitmap(x._bitmap), _bm_erased(x._bm_erased)
  2151. {
  2152. _set_num_items(0);
  2153. _set_num_alloc(0);
  2154. uint32_t num_items = x._num_items();
  2155. if (num_items)
  2156. {
  2157. _group = _allocate_group(a, num_items /* , true */);
  2158. _set_num_items(num_items);
  2159. std::uninitialized_copy(x._group, x._group + num_items, _group);
  2160. }
  2161. }
  2162. ~sparsegroup() { assert(_group == 0); if (_group) exit(1); }
  2163. void destruct(allocator_type& a) { _free_group(a, _num_alloc()); }
  2164. // Many STL algorithms use swap instead of copy constructors
  2165. void swap(sparsegroup& x)
  2166. {
  2167. using std::swap;
  2168. swap(_group, x._group);
  2169. swap(_bitmap, x._bitmap);
  2170. swap(_bm_erased, x._bm_erased);
  2171. #ifdef SPP_STORE_NUM_ITEMS
  2172. swap(_num_buckets, x._num_buckets);
  2173. swap(_num_allocated, x._num_allocated);
  2174. #endif
  2175. }
  2176. // It's always nice to be able to clear a table without deallocating it
  2177. void clear(Alloc &alloc, bool erased)
  2178. {
  2179. _free_group(alloc, _num_alloc());
  2180. _bitmap = 0;
  2181. if (erased)
  2182. _bm_erased = 0;
  2183. _set_num_items(0);
  2184. _set_num_alloc(0);
  2185. }
  2186. // Functions that tell you about size. Alas, these aren't so useful
  2187. // because our table is always fixed size.
  2188. size_type size() const { return static_cast<size_type>(SPP_GROUP_SIZE); }
  2189. size_type max_size() const { return static_cast<size_type>(SPP_GROUP_SIZE); }
  2190. bool empty() const { return false; }
  2191. // We also may want to know how many *used* buckets there are
  2192. size_type num_nonempty() const { return (size_type)_num_items(); }
  2193. // get()/set() are explicitly const/non-const. You can use [] if
  2194. // you want something that can be either (potentially more expensive).
  2195. const_reference get(size_type i) const
  2196. {
  2197. if (_bmtest(i)) // bucket i is occupied
  2198. return (const_reference)_group[pos_to_offset(i)];
  2199. else
  2200. return default_value(); // return the default reference
  2201. }
  2202. // TODO(csilvers): make protected + friend
  2203. // This is used by sparse_hashtable to get an element from the table
  2204. // when we know it exists.
  2205. reference unsafe_get(size_type i) const
  2206. {
  2207. // assert(_bmtest(i));
  2208. return (reference)_group[pos_to_offset(i)];
  2209. }
  2210. typedef std::pair<mutable_pointer, bool> SetResult;
  2211. // returns a reference which can be assigned, so we have to create an entry if not
  2212. // already there
  2213. // -------------------------------------------------------------------------------
  2214. reference mutating_get(Alloc &alloc, size_type i)
  2215. {
  2216. // fills bucket i before getting
  2217. if (!_bmtest(i))
  2218. {
  2219. SetResult sr = set(alloc, i, false);
  2220. if (!sr.second)
  2221. ::new (sr.first) mutable_value_type();
  2222. return *((pointer)sr.first);
  2223. }
  2224. return _group[pos_to_offset(i)];
  2225. }
  2226. // Syntactic sugar. It's easy to return a const reference. To
  2227. // return a non-const reference, we need to use the assigner adaptor.
  2228. const_reference operator[](size_type i) const
  2229. {
  2230. return get(i);
  2231. }
  2232. element_adaptor operator[](size_type i)
  2233. {
  2234. return element_adaptor(this, i);
  2235. }
  2236. private:
  2237. typedef spp_::integral_constant<bool,
  2238. (spp_::is_relocatable<value_type>::value &&
  2239. spp_::is_same<allocator_type,
  2240. spp_::libc_allocator_with_realloc<mutable_value_type> >::value)>
  2241. realloc_and_memmove_ok;
  2242. // Our default allocator - try to merge memory buffers
  2243. // right now it uses Google's traits, but we should use something like folly::IsRelocatable
  2244. // return true if the slot was constructed (i.e. contains a valid mutable_value_type
  2245. // ---------------------------------------------------------------------------------
  2246. bool _set_aux(Alloc &alloc, size_type offset, spp_::true_type)
  2247. {
  2248. //static int x=0; if (++x < 10) printf("x\n"); // check we are getting here
  2249. uint32_t num_items = _num_items();
  2250. uint32_t num_alloc = _sizing(num_items);
  2251. if (num_items == num_alloc)
  2252. {
  2253. num_alloc = _sizing(num_items + 1);
  2254. _group = alloc.reallocate(_group, num_alloc);
  2255. _set_num_alloc(num_alloc);
  2256. }
  2257. for (uint32_t i = num_items; i > offset; --i)
  2258. memcpy(_group + i, _group + i-1, sizeof(*_group));
  2259. return false;
  2260. }
  2261. // Create space at _group[offset], without special assumptions about value_type
  2262. // and allocator_type, with a default value
  2263. // return true if the slot was constructed (i.e. contains a valid mutable_value_type
  2264. // ---------------------------------------------------------------------------------
  2265. bool _set_aux(Alloc &alloc, size_type offset, spp_::false_type)
  2266. {
  2267. uint32_t num_items = _num_items();
  2268. uint32_t num_alloc = _sizing(num_items);
  2269. //assert(num_alloc == (uint32_t)_num_allocated);
  2270. if (num_items < num_alloc)
  2271. {
  2272. // create new object at end and rotate it to position
  2273. ::new (&_group[num_items]) mutable_value_type();
  2274. std::rotate(_group + offset, _group + num_items, _group + num_items + 1);
  2275. return true;
  2276. }
  2277. // This is valid because 0 <= offset <= num_items
  2278. mutable_pointer p = _allocate_group(alloc, _sizing(num_items + 1));
  2279. if (offset)
  2280. std::uninitialized_copy(MK_MOVE_IT(_group),
  2281. MK_MOVE_IT(_group + offset),
  2282. p);
  2283. if (num_items > offset)
  2284. std::uninitialized_copy(MK_MOVE_IT(_group + offset),
  2285. MK_MOVE_IT(_group + num_items),
  2286. p + offset + 1);
  2287. _free_group(alloc, num_alloc);
  2288. _group = p;
  2289. return false;
  2290. }
  2291. public:
  2292. // TODO(austern): Make this exception safe: handle exceptions from
  2293. // value_type's copy constructor.
  2294. // return true if the slot was constructed (i.e. contains a valid mutable_value_type)
  2295. // ----------------------------------------------------------------------------------
  2296. bool _set(Alloc &alloc, size_type i, size_type offset, bool erased)
  2297. {
  2298. if (erased)
  2299. {
  2300. // assert(_bme_test(i));
  2301. _bme_clear(i);
  2302. }
  2303. if (!_bmtest(i))
  2304. {
  2305. bool res = _set_aux(alloc, offset, realloc_and_memmove_ok());
  2306. _incr_num_items();
  2307. _bmset(i);
  2308. return res;
  2309. }
  2310. return true;
  2311. }
  2312. // This returns a pair (first is a pointer to the item's location, second is whether
  2313. // that location is constructed (i.e. contains a valid mutable_value_type)
  2314. // ---------------------------------------------------------------------------------
  2315. SetResult set(Alloc &alloc, size_type i, bool erased)
  2316. {
  2317. size_type offset = pos_to_offset(i);
  2318. bool constructed = _set(alloc, i, offset, erased); // may change _group pointer
  2319. return std::make_pair(_group + offset, constructed);
  2320. }
  2321. // used in _move_from (where we can move the old value instead of copying it
  2322. // -------------------------------------------------------------------------
  2323. void move(Alloc &alloc, size_type i, reference val)
  2324. {
  2325. // assert(!_bmtest(i));
  2326. size_type offset = pos_to_offset(i);
  2327. if (!_set(alloc, i, offset, false))
  2328. ::new (&_group[offset]) mutable_value_type();
  2329. using std::swap;
  2330. swap(_group[offset], spp_mutable_ref(val)); // called from _move_from, OK to swap
  2331. }
  2332. // We let you see if a bucket is non-empty without retrieving it
  2333. // -------------------------------------------------------------
  2334. bool test(size_type i) const
  2335. {
  2336. return _bmtest(i);
  2337. }
  2338. // also tests for erased values
  2339. // ----------------------------
  2340. bool test_strict(size_type i) const
  2341. {
  2342. return _bmtest_strict(i);
  2343. }
  2344. private:
  2345. // Shrink the array, assuming value_type has trivial copy
  2346. // constructor and destructor, and the allocator_type is the default
  2347. // libc_allocator_with_alloc.
  2348. // -----------------------------------------------------------------------
  2349. void _group_erase_aux(Alloc &alloc, size_type offset, spp_::true_type)
  2350. {
  2351. // static int x=0; if (++x < 10) printf("Y\n"); // check we are getting here
  2352. uint32_t num_items = _num_items();
  2353. uint32_t num_alloc = _sizing(num_items);
  2354. if (num_items == 1)
  2355. {
  2356. assert(offset == 0);
  2357. _free_group(alloc, num_alloc);
  2358. _set_num_alloc(0);
  2359. return;
  2360. }
  2361. _group[offset].~mutable_value_type();
  2362. for (size_type i = offset; i < num_items - 1; ++i)
  2363. memcpy(_group + i, _group + i + 1, sizeof(*_group));
  2364. if (_sizing(num_items - 1) != num_alloc)
  2365. {
  2366. num_alloc = _sizing(num_items - 1);
  2367. assert(num_alloc); // because we have at least 1 item left
  2368. _set_num_alloc(num_alloc);
  2369. _group = alloc.reallocate(_group, num_alloc);
  2370. }
  2371. }
  2372. // Shrink the array, without any special assumptions about value_type and
  2373. // allocator_type.
  2374. // --------------------------------------------------------------------------
  2375. void _group_erase_aux(Alloc &alloc, size_type offset, spp_::false_type)
  2376. {
  2377. uint32_t num_items = _num_items();
  2378. uint32_t num_alloc = _sizing(num_items);
  2379. if (_sizing(num_items - 1) != num_alloc)
  2380. {
  2381. mutable_pointer p = 0;
  2382. if (num_items > 1)
  2383. {
  2384. p = _allocate_group(alloc, num_items - 1);
  2385. if (offset)
  2386. std::uninitialized_copy(MK_MOVE_IT(_group),
  2387. MK_MOVE_IT(_group + offset),
  2388. p);
  2389. if (static_cast<uint32_t>(offset + 1) < num_items)
  2390. std::uninitialized_copy(MK_MOVE_IT(_group + offset + 1),
  2391. MK_MOVE_IT(_group + num_items),
  2392. p + offset);
  2393. }
  2394. else
  2395. {
  2396. assert(offset == 0);
  2397. _set_num_alloc(0);
  2398. }
  2399. _free_group(alloc, num_alloc);
  2400. _group = p;
  2401. }
  2402. else
  2403. {
  2404. std::rotate(_group + offset, _group + offset + 1, _group + num_items);
  2405. _group[num_items - 1].~mutable_value_type();
  2406. }
  2407. }
  2408. void _group_erase(Alloc &alloc, size_type offset)
  2409. {
  2410. _group_erase_aux(alloc, offset, realloc_and_memmove_ok());
  2411. }
  2412. public:
  2413. template <class twod_iter>
  2414. bool erase_ne(Alloc &alloc, twod_iter &it)
  2415. {
  2416. assert(_group && it.col_current != ne_end());
  2417. size_type offset = (size_type)(it.col_current - ne_begin());
  2418. size_type pos = offset_to_pos(offset);
  2419. if (_num_items() <= 1)
  2420. {
  2421. clear(alloc, false);
  2422. it.col_current = 0;
  2423. }
  2424. else
  2425. {
  2426. _group_erase(alloc, offset);
  2427. _decr_num_items();
  2428. _bmclear(pos);
  2429. // in case _group_erase reallocated the buffer
  2430. it.col_current = reinterpret_cast<pointer>(_group) + offset;
  2431. }
  2432. _bme_set(pos); // remember that this position has been erased
  2433. it.advance_past_end();
  2434. return true;
  2435. }
  2436. // This takes the specified elements out of the group. This is
  2437. // "undefining", rather than "clearing".
  2438. // TODO(austern): Make this exception safe: handle exceptions from
  2439. // value_type's copy constructor.
  2440. // ---------------------------------------------------------------
  2441. void erase(Alloc &alloc, size_type i)
  2442. {
  2443. if (_bmtest(i))
  2444. {
  2445. // trivial to erase empty bucket
  2446. if (_num_items() == 1)
  2447. clear(alloc, false);
  2448. else
  2449. {
  2450. _group_erase(alloc, pos_to_offset(i));
  2451. _decr_num_items();
  2452. _bmclear(i);
  2453. }
  2454. _bme_set(i); // remember that this position has been erased
  2455. }
  2456. }
  2457. // I/O
  2458. // We support reading and writing groups to disk. We don't store
  2459. // the actual array contents (which we don't know how to store),
  2460. // just the bitmap and size. Meant to be used with table I/O.
  2461. // --------------------------------------------------------------
  2462. template <typename OUTPUT> bool write_metadata(OUTPUT *fp) const
  2463. {
  2464. // warning: we write 4 or 8 bytes for the bitmap, instead of 6 in the
  2465. // original google sparsehash
  2466. // ------------------------------------------------------------------
  2467. if (!sparsehash_internal::write_data(fp, &_bitmap, sizeof(_bitmap)))
  2468. return false;
  2469. return true;
  2470. }
  2471. // Reading destroys the old group contents! Returns true if all was ok.
  2472. template <typename INPUT> bool read_metadata(Alloc &alloc, INPUT *fp)
  2473. {
  2474. clear(alloc, true);
  2475. if (!sparsehash_internal::read_data(fp, &_bitmap, sizeof(_bitmap)))
  2476. return false;
  2477. // We'll allocate the space, but we won't fill it: it will be
  2478. // left as uninitialized raw memory.
  2479. uint32_t num_items = spp_popcount(_bitmap); // yes, _num_buckets not set
  2480. _set_num_items(num_items);
  2481. _group = num_items ? _allocate_group(alloc, num_items/* , true */) : 0;
  2482. return true;
  2483. }
  2484. // Again, only meaningful if value_type is a POD.
  2485. template <typename INPUT> bool read_nopointer_data(INPUT *fp)
  2486. {
  2487. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  2488. if (!sparsehash_internal::read_data(fp, &(*it), sizeof(*it)))
  2489. return false;
  2490. return true;
  2491. }
  2492. // If your keys and values are simple enough, we can write them
  2493. // to disk for you. "simple enough" means POD and no pointers.
  2494. // However, we don't try to normalize endianness.
  2495. // ------------------------------------------------------------
  2496. template <typename OUTPUT> bool write_nopointer_data(OUTPUT *fp) const
  2497. {
  2498. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  2499. if (!sparsehash_internal::write_data(fp, &(*it), sizeof(*it)))
  2500. return false;
  2501. return true;
  2502. }
  2503. // Comparisons. We only need to define == and < -- we get
  2504. // != > <= >= via relops.h (which we happily included above).
  2505. // Note the comparisons are pretty arbitrary: we compare
  2506. // values of the first index that isn't equal (using default
  2507. // value for empty buckets).
  2508. // ---------------------------------------------------------
  2509. bool operator==(const sparsegroup& x) const
  2510. {
  2511. return (_bitmap == x._bitmap &&
  2512. _bm_erased == x._bm_erased &&
  2513. std::equal(_group, _group + _num_items(), x._group));
  2514. }
  2515. bool operator<(const sparsegroup& x) const
  2516. {
  2517. // also from <algorithm>
  2518. return std::lexicographical_compare(_group, _group + _num_items(),
  2519. x._group, x._group + x._num_items());
  2520. }
  2521. bool operator!=(const sparsegroup& x) const { return !(*this == x); }
  2522. bool operator<=(const sparsegroup& x) const { return !(x < *this); }
  2523. bool operator> (const sparsegroup& x) const { return x < *this; }
  2524. bool operator>=(const sparsegroup& x) const { return !(*this < x); }
  2525. void mark() { _group = (mutable_value_type *)static_cast<uintptr_t>(-1); }
  2526. bool is_marked() const { return _group == (mutable_value_type *)static_cast<uintptr_t>(-1); }
  2527. private:
  2528. // ---------------------------------------------------------------------------
  2529. template <class A>
  2530. class alloc_impl : public A
  2531. {
  2532. public:
  2533. typedef typename A::pointer pointer;
  2534. typedef typename A::size_type size_type;
  2535. // Convert a normal allocator to one that has realloc_or_die()
  2536. explicit alloc_impl(const A& a) : A(a) { }
  2537. // realloc_or_die should only be used when using the default
  2538. // allocator (libc_allocator_with_realloc).
  2539. pointer realloc_or_die(pointer /*ptr*/, size_type /*n*/)
  2540. {
  2541. fprintf(stderr, "realloc_or_die is only supported for "
  2542. "libc_allocator_with_realloc\n");
  2543. exit(1);
  2544. return NULL;
  2545. }
  2546. };
  2547. // A template specialization of alloc_impl for
  2548. // libc_allocator_with_realloc that can handle realloc_or_die.
  2549. // -----------------------------------------------------------
  2550. template <class A>
  2551. class alloc_impl<libc_allocator_with_realloc<A> >
  2552. : public libc_allocator_with_realloc<A>
  2553. {
  2554. public:
  2555. typedef typename libc_allocator_with_realloc<A>::pointer pointer;
  2556. typedef typename libc_allocator_with_realloc<A>::size_type size_type;
  2557. explicit alloc_impl(const libc_allocator_with_realloc<A>& a)
  2558. : libc_allocator_with_realloc<A>(a)
  2559. { }
  2560. pointer realloc_or_die(pointer ptr, size_type n)
  2561. {
  2562. pointer retval = this->reallocate(ptr, n);
  2563. if (retval == NULL) {
  2564. fprintf(stderr, "sparsehash: FATAL ERROR: failed to reallocate "
  2565. "%lu elements for ptr %p", static_cast<unsigned long>(n), ptr);
  2566. exit(1);
  2567. }
  2568. return retval;
  2569. }
  2570. };
  2571. #ifdef SPP_STORE_NUM_ITEMS
  2572. uint32_t _num_items() const { return (uint32_t)_num_buckets; }
  2573. void _set_num_items(uint32_t val) { _num_buckets = static_cast<size_type>(val); }
  2574. void _incr_num_items() { ++_num_buckets; }
  2575. void _decr_num_items() { --_num_buckets; }
  2576. uint32_t _num_alloc() const { return (uint32_t)_num_allocated; }
  2577. void _set_num_alloc(uint32_t val) { _num_allocated = static_cast<size_type>(val); }
  2578. #else
  2579. uint32_t _num_items() const { return spp_popcount(_bitmap); }
  2580. void _set_num_items(uint32_t ) { }
  2581. void _incr_num_items() { }
  2582. void _decr_num_items() { }
  2583. uint32_t _num_alloc() const { return _sizing(_num_items()); }
  2584. void _set_num_alloc(uint32_t val) { }
  2585. #endif
  2586. // The actual data
  2587. // ---------------
  2588. mutable_value_type * _group; // (small) array of T's
  2589. group_bm_type _bitmap;
  2590. group_bm_type _bm_erased; // ones where items have been erased
  2591. #ifdef SPP_STORE_NUM_ITEMS
  2592. size_type _num_buckets;
  2593. size_type _num_allocated;
  2594. #endif
  2595. };
  2596. // ---------------------------------------------------------------------------
  2597. // We need a global swap as well
  2598. // ---------------------------------------------------------------------------
  2599. template <class T, class Alloc>
  2600. inline void swap(sparsegroup<T,Alloc> &x, sparsegroup<T,Alloc> &y)
  2601. {
  2602. x.swap(y);
  2603. }
  2604. // ---------------------------------------------------------------------------
  2605. // ---------------------------------------------------------------------------
  2606. template <class T, class Alloc = libc_allocator_with_realloc<T> >
  2607. class sparsetable
  2608. {
  2609. private:
  2610. typedef typename Alloc::template rebind<T>::other value_alloc_type;
  2611. typedef typename Alloc::template rebind<
  2612. sparsegroup<T, value_alloc_type> >::other group_alloc_type;
  2613. typedef typename group_alloc_type::size_type group_size_type;
  2614. typedef T mutable_value_type;
  2615. typedef mutable_value_type* mutable_pointer;
  2616. typedef const mutable_value_type* const_mutable_pointer;
  2617. public:
  2618. // Basic types
  2619. // -----------
  2620. typedef typename spp::cvt<T>::type value_type;
  2621. typedef Alloc allocator_type;
  2622. typedef typename value_alloc_type::size_type size_type;
  2623. typedef typename value_alloc_type::difference_type difference_type;
  2624. typedef value_type& reference;
  2625. typedef const value_type& const_reference;
  2626. typedef value_type* pointer;
  2627. typedef const value_type* const_pointer;
  2628. typedef sparsegroup<T, value_alloc_type> group_type;
  2629. typedef group_type& GroupsReference;
  2630. typedef const group_type& GroupsConstReference;
  2631. typedef typename group_type::ne_iterator ColIterator;
  2632. typedef typename group_type::const_ne_iterator ColConstIterator;
  2633. typedef table_iterator<sparsetable<T, Alloc> > iterator; // defined with index
  2634. typedef const_table_iterator<sparsetable<T, Alloc> > const_iterator; // defined with index
  2635. typedef table_element_adaptor<sparsetable<T, Alloc> > element_adaptor;
  2636. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  2637. typedef std::reverse_iterator<iterator> reverse_iterator;
  2638. // These are our special iterators, that go over non-empty buckets in a
  2639. // table. These aren't const only because you can change non-empty bcks.
  2640. // ----------------------------------------------------------------------
  2641. typedef Two_d_iterator<T,
  2642. group_type *,
  2643. ColIterator,
  2644. std::bidirectional_iterator_tag> ne_iterator;
  2645. typedef Two_d_iterator<const T,
  2646. const group_type *,
  2647. ColConstIterator,
  2648. std::bidirectional_iterator_tag> const_ne_iterator;
  2649. // Another special iterator: it frees memory as it iterates (used to resize).
  2650. // Obviously, you can only iterate over it once, which is why it's an input iterator
  2651. // ---------------------------------------------------------------------------------
  2652. typedef Two_d_destructive_iterator<T,
  2653. group_type *,
  2654. ColIterator,
  2655. std::input_iterator_tag,
  2656. allocator_type> destructive_iterator;
  2657. typedef std::reverse_iterator<ne_iterator> reverse_ne_iterator;
  2658. typedef std::reverse_iterator<const_ne_iterator> const_reverse_ne_iterator;
  2659. // Iterator functions
  2660. // ------------------
  2661. iterator begin() { return iterator(this, 0); }
  2662. const_iterator begin() const { return const_iterator(this, 0); }
  2663. const_iterator cbegin() const { return const_iterator(this, 0); }
  2664. iterator end() { return iterator(this, size()); }
  2665. const_iterator end() const { return const_iterator(this, size()); }
  2666. const_iterator cend() const { return const_iterator(this, size()); }
  2667. reverse_iterator rbegin() { return reverse_iterator(end()); }
  2668. const_reverse_iterator rbegin() const { return const_reverse_iterator(cend()); }
  2669. const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); }
  2670. reverse_iterator rend() { return reverse_iterator(begin()); }
  2671. const_reverse_iterator rend() const { return const_reverse_iterator(cbegin()); }
  2672. const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); }
  2673. // Versions for our special non-empty iterator
  2674. // ------------------------------------------
  2675. ne_iterator ne_begin() { return ne_iterator (_first_group); }
  2676. const_ne_iterator ne_begin() const { return const_ne_iterator(_first_group); }
  2677. const_ne_iterator ne_cbegin() const { return const_ne_iterator(_first_group); }
  2678. ne_iterator ne_end() { return ne_iterator (_last_group); }
  2679. const_ne_iterator ne_end() const { return const_ne_iterator(_last_group); }
  2680. const_ne_iterator ne_cend() const { return const_ne_iterator(_last_group); }
  2681. reverse_ne_iterator ne_rbegin() { return reverse_ne_iterator(ne_end()); }
  2682. const_reverse_ne_iterator ne_rbegin() const { return const_reverse_ne_iterator(ne_end()); }
  2683. const_reverse_ne_iterator ne_crbegin() const { return const_reverse_ne_iterator(ne_end()); }
  2684. reverse_ne_iterator ne_rend() { return reverse_ne_iterator(ne_begin()); }
  2685. const_reverse_ne_iterator ne_rend() const { return const_reverse_ne_iterator(ne_begin()); }
  2686. const_reverse_ne_iterator ne_crend() const { return const_reverse_ne_iterator(ne_begin()); }
  2687. destructive_iterator destructive_begin()
  2688. {
  2689. return destructive_iterator(_alloc, _first_group);
  2690. }
  2691. destructive_iterator destructive_end()
  2692. {
  2693. return destructive_iterator(_alloc, _last_group);
  2694. }
  2695. // How to deal with the proper group
  2696. static group_size_type num_groups(group_size_type num)
  2697. {
  2698. // how many to hold num buckets
  2699. return num == 0 ? (group_size_type)0 :
  2700. (group_size_type)(((num-1) / SPP_GROUP_SIZE) + 1);
  2701. }
  2702. typename group_type::size_type pos_in_group(size_type i) const
  2703. {
  2704. return static_cast<typename group_type::size_type>(i & SPP_MASK_);
  2705. }
  2706. size_type group_num(size_type i) const
  2707. {
  2708. return (size_type)(i >> SPP_SHIFT_);
  2709. }
  2710. GroupsReference which_group(size_type i)
  2711. {
  2712. return _first_group[group_num(i)];
  2713. }
  2714. GroupsConstReference which_group(size_type i) const
  2715. {
  2716. return _first_group[group_num(i)];
  2717. }
  2718. void _alloc_group_array(group_size_type sz, group_type *&first, group_type *&last)
  2719. {
  2720. if (sz)
  2721. {
  2722. first = _group_alloc.allocate((size_type)(sz + 1)); // + 1 for end marker
  2723. first[sz].mark(); // for the ne_iterator
  2724. last = first + sz;
  2725. }
  2726. }
  2727. void _free_group_array(group_type *&first, group_type *&last)
  2728. {
  2729. if (first)
  2730. {
  2731. _group_alloc.deallocate(first, (group_size_type)(last - first + 1)); // + 1 for end marker
  2732. first = last = 0;
  2733. }
  2734. }
  2735. void _allocate_groups(size_type sz)
  2736. {
  2737. if (sz)
  2738. {
  2739. _alloc_group_array(sz, _first_group, _last_group);
  2740. std::uninitialized_fill(_first_group, _last_group, group_type());
  2741. }
  2742. }
  2743. void _free_groups()
  2744. {
  2745. if (_first_group)
  2746. {
  2747. for (group_type *g = _first_group; g != _last_group; ++g)
  2748. g->destruct(_alloc);
  2749. _free_group_array(_first_group, _last_group);
  2750. }
  2751. }
  2752. void _cleanup()
  2753. {
  2754. _free_groups(); // sets _first_group = _last_group = 0
  2755. _table_size = 0;
  2756. _num_buckets = 0;
  2757. }
  2758. void _init()
  2759. {
  2760. _first_group = 0;
  2761. _last_group = 0;
  2762. _table_size = 0;
  2763. _num_buckets = 0;
  2764. }
  2765. void _copy(const sparsetable &o)
  2766. {
  2767. _table_size = o._table_size;
  2768. _num_buckets = o._num_buckets;
  2769. _alloc = o._alloc; // todo - copy or move allocator according to...
  2770. _group_alloc = o._group_alloc; // http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map
  2771. group_size_type sz = (group_size_type)(o._last_group - o._first_group);
  2772. if (sz)
  2773. {
  2774. _alloc_group_array(sz, _first_group, _last_group);
  2775. for (group_size_type i=0; i<sz; ++i)
  2776. new (_first_group + i) group_type(o._first_group[i], _alloc);
  2777. }
  2778. }
  2779. public:
  2780. // Constructors -- default, normal (when you specify size), and copy
  2781. explicit sparsetable(size_type sz = 0, const Alloc &alloc = Alloc()) :
  2782. _first_group(0),
  2783. _last_group(0),
  2784. _table_size(sz),
  2785. _num_buckets(0),
  2786. _alloc(alloc) // todo - copy or move allocator according to
  2787. // http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map
  2788. {
  2789. _allocate_groups(num_groups(sz));
  2790. }
  2791. ~sparsetable()
  2792. {
  2793. _free_groups();
  2794. }
  2795. sparsetable(const sparsetable &o)
  2796. {
  2797. _init();
  2798. _copy(o);
  2799. }
  2800. sparsetable& operator=(const sparsetable &o)
  2801. {
  2802. _cleanup();
  2803. _copy(o);
  2804. return *this;
  2805. }
  2806. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  2807. sparsetable(sparsetable&& o)
  2808. {
  2809. _init();
  2810. this->swap(o);
  2811. }
  2812. sparsetable(sparsetable&& o, const Alloc &alloc)
  2813. {
  2814. _init();
  2815. this->swap(o);
  2816. _alloc = alloc; // [gp todo] is this correct?
  2817. }
  2818. sparsetable& operator=(sparsetable&& o)
  2819. {
  2820. _cleanup();
  2821. this->swap(o);
  2822. return *this;
  2823. }
  2824. #endif
  2825. // Many STL algorithms use swap instead of copy constructors
  2826. void swap(sparsetable& o)
  2827. {
  2828. using std::swap;
  2829. swap(_first_group, o._first_group);
  2830. swap(_last_group, o._last_group);
  2831. swap(_table_size, o._table_size);
  2832. swap(_num_buckets, o._num_buckets);
  2833. if (_alloc != o._alloc)
  2834. swap(_alloc, o._alloc);
  2835. if (_group_alloc != o._group_alloc)
  2836. swap(_group_alloc, o._group_alloc);
  2837. }
  2838. // It's always nice to be able to clear a table without deallocating it
  2839. void clear()
  2840. {
  2841. _free_groups();
  2842. _num_buckets = 0;
  2843. _table_size = 0;
  2844. }
  2845. inline allocator_type get_allocator() const
  2846. {
  2847. return _alloc;
  2848. }
  2849. // Functions that tell you about size.
  2850. // NOTE: empty() is non-intuitive! It does not tell you the number
  2851. // of not-empty buckets (use num_nonempty() for that). Instead
  2852. // it says whether you've allocated any buckets or not.
  2853. // ----------------------------------------------------------------
  2854. size_type size() const { return _table_size; }
  2855. size_type max_size() const { return _alloc.max_size(); }
  2856. bool empty() const { return _table_size == 0; }
  2857. size_type num_nonempty() const { return _num_buckets; }
  2858. // OK, we'll let you resize one of these puppies
  2859. void resize(size_type new_size)
  2860. {
  2861. group_size_type sz = num_groups(new_size);
  2862. group_size_type old_sz = (group_size_type)(_last_group - _first_group);
  2863. if (sz != old_sz)
  2864. {
  2865. // resize group array
  2866. // ------------------
  2867. group_type *first = 0, *last = 0;
  2868. if (sz)
  2869. {
  2870. _alloc_group_array(sz, first, last);
  2871. memcpy(first, _first_group, sizeof(*first) * (std::min)(sz, old_sz));
  2872. }
  2873. if (sz < old_sz)
  2874. {
  2875. for (group_type *g = _first_group + sz; g != _last_group; ++g)
  2876. g->destruct(_alloc);
  2877. }
  2878. else
  2879. std::uninitialized_fill(first + old_sz, last, group_type());
  2880. _free_group_array(_first_group, _last_group);
  2881. _first_group = first;
  2882. _last_group = last;
  2883. }
  2884. #if 0
  2885. // used only in test program
  2886. // todo: fix if sparsetable to be used directly
  2887. // --------------------------------------------
  2888. if (new_size < _table_size)
  2889. {
  2890. // lower num_buckets, clear last group
  2891. if (pos_in_group(new_size) > 0) // need to clear inside last group
  2892. groups.back().erase(_alloc, groups.back().begin() + pos_in_group(new_size),
  2893. groups.back().end());
  2894. _num_buckets = 0; // refigure # of used buckets
  2895. for (const group_type *group = _first_group; group != _last_group; ++group)
  2896. _num_buckets += group->num_nonempty();
  2897. }
  2898. #endif
  2899. _table_size = new_size;
  2900. }
  2901. // We let you see if a bucket is non-empty without retrieving it
  2902. // -------------------------------------------------------------
  2903. bool test(size_type i) const
  2904. {
  2905. // assert(i < _table_size);
  2906. return which_group(i).test(pos_in_group(i));
  2907. }
  2908. // also tests for erased values
  2909. // ----------------------------
  2910. bool test_strict(size_type i) const
  2911. {
  2912. // assert(i < _table_size);
  2913. return which_group(i).test_strict(pos_in_group(i));
  2914. }
  2915. friend struct GrpPos;
  2916. struct GrpPos
  2917. {
  2918. typedef typename sparsetable::ne_iterator ne_iter;
  2919. GrpPos(const sparsetable &table, size_type i) :
  2920. grp(table.which_group(i)), pos(table.pos_in_group(i)) {}
  2921. bool test_strict() const { return grp.test_strict(pos); }
  2922. bool test() const { return grp.test(pos); }
  2923. typename sparsetable::reference unsafe_get() const { return grp.unsafe_get(pos); }
  2924. ne_iter get_iter(typename sparsetable::reference ref)
  2925. {
  2926. return ne_iter((group_type *)&grp, &ref);
  2927. }
  2928. void erase(sparsetable &table) // item *must* be present
  2929. {
  2930. assert(table._num_buckets);
  2931. ((group_type &)grp).erase(table._alloc, pos);
  2932. --table._num_buckets;
  2933. }
  2934. private:
  2935. GrpPos* operator=(const GrpPos&);
  2936. const group_type &grp;
  2937. typename group_type::size_type pos;
  2938. };
  2939. bool test(iterator pos) const
  2940. {
  2941. return which_group(pos.pos).test(pos_in_group(pos.pos));
  2942. }
  2943. bool test(const_iterator pos) const
  2944. {
  2945. return which_group(pos.pos).test(pos_in_group(pos.pos));
  2946. }
  2947. // We only return const_references because it's really hard to
  2948. // return something settable for empty buckets. Use set() instead.
  2949. const_reference get(size_type i) const
  2950. {
  2951. assert(i < _table_size);
  2952. return which_group(i).get(pos_in_group(i));
  2953. }
  2954. // TODO(csilvers): make protected + friend
  2955. // This is used by sparse_hashtable to get an element from the table
  2956. // when we know it exists (because the caller has called test(i)).
  2957. // -----------------------------------------------------------------
  2958. reference unsafe_get(size_type i) const
  2959. {
  2960. assert(i < _table_size);
  2961. // assert(test(i));
  2962. return which_group(i).unsafe_get(pos_in_group(i));
  2963. }
  2964. // TODO(csilvers): make protected + friend element_adaptor
  2965. reference mutating_get(size_type i)
  2966. {
  2967. // fills bucket i before getting
  2968. assert(i < _table_size);
  2969. GroupsReference grp(which_group(i));
  2970. typename group_type::size_type old_numbuckets = grp.num_nonempty();
  2971. reference retval = grp.mutating_get(_alloc, pos_in_group(i));
  2972. _num_buckets += grp.num_nonempty() - old_numbuckets;
  2973. return retval;
  2974. }
  2975. // Syntactic sugar. As in sparsegroup, the non-const version is harder
  2976. const_reference operator[](size_type i) const
  2977. {
  2978. return get(i);
  2979. }
  2980. element_adaptor operator[](size_type i)
  2981. {
  2982. return element_adaptor(this, i);
  2983. }
  2984. // Needed for hashtables, gets as a ne_iterator. Crashes for empty bcks
  2985. const_ne_iterator get_iter(size_type i) const
  2986. {
  2987. //assert(test(i)); // how can a ne_iterator point to an empty bucket?
  2988. size_type grp_idx = group_num(i);
  2989. return const_ne_iterator(_first_group + grp_idx,
  2990. (_first_group[grp_idx].ne_begin() +
  2991. _first_group[grp_idx].pos_to_offset(pos_in_group(i))));
  2992. }
  2993. const_ne_iterator get_iter(size_type i, ColIterator col_it) const
  2994. {
  2995. return const_ne_iterator(_first_group + group_num(i), col_it);
  2996. }
  2997. // For nonempty we can return a non-const version
  2998. ne_iterator get_iter(size_type i)
  2999. {
  3000. //assert(test(i)); // how can a nonempty_iterator point to an empty bucket?
  3001. size_type grp_idx = group_num(i);
  3002. return ne_iterator(_first_group + grp_idx,
  3003. (_first_group[grp_idx].ne_begin() +
  3004. _first_group[grp_idx].pos_to_offset(pos_in_group(i))));
  3005. }
  3006. ne_iterator get_iter(size_type i, ColIterator col_it)
  3007. {
  3008. return ne_iterator(_first_group + group_num(i), col_it);
  3009. }
  3010. // And the reverse transformation.
  3011. size_type get_pos(const const_ne_iterator& it) const
  3012. {
  3013. difference_type current_row = it.row_current - _first_group;
  3014. difference_type current_col = (it.col_current - _first_group[current_row].ne_begin());
  3015. return ((current_row * SPP_GROUP_SIZE) +
  3016. _first_group[current_row].offset_to_pos(current_col));
  3017. }
  3018. // This returns a reference to the inserted item (which is a copy of val)
  3019. // The trick is to figure out whether we're replacing or inserting anew
  3020. // ----------------------------------------------------------------------
  3021. reference set(size_type i, const_reference val, bool erased = false)
  3022. {
  3023. assert(i < _table_size);
  3024. group_type &group = which_group(i);
  3025. typename group_type::size_type old_numbuckets = group.num_nonempty();
  3026. typename group_type::SetResult sr(group.set(_alloc, pos_in_group(i), erased));
  3027. if (!sr.second)
  3028. ::new (sr.first) mutable_value_type(val);
  3029. else
  3030. *sr.first = spp_const_mutable_ref(val);
  3031. _num_buckets += group.num_nonempty() - old_numbuckets;
  3032. return *((pointer)sr.first);
  3033. }
  3034. // used in _move_from (where we can move the old value instead of copying it
  3035. void move(size_type i, reference val)
  3036. {
  3037. assert(i < _table_size);
  3038. which_group(i).move(_alloc, pos_in_group(i), val);
  3039. ++_num_buckets;
  3040. }
  3041. // This takes the specified elements out of the table.
  3042. // --------------------------------------------------
  3043. void erase(size_type i)
  3044. {
  3045. assert(i < _table_size);
  3046. GroupsReference grp(which_group(i));
  3047. typename group_type::size_type old_numbuckets = grp.num_nonempty();
  3048. grp.erase(_alloc, pos_in_group(i));
  3049. _num_buckets += grp.num_nonempty() - old_numbuckets;
  3050. }
  3051. void erase(iterator pos)
  3052. {
  3053. erase(pos.pos);
  3054. }
  3055. void erase(iterator start_it, iterator end_it)
  3056. {
  3057. // This could be more efficient, but then we'd need to figure
  3058. // out if we spanned groups or not. Doesn't seem worth it.
  3059. for (; start_it != end_it; ++start_it)
  3060. erase(start_it);
  3061. }
  3062. const_ne_iterator erase(const_ne_iterator it)
  3063. {
  3064. ne_iterator res(it);
  3065. if (res.row_current->erase_ne(_alloc, res))
  3066. _num_buckets--;
  3067. return res;
  3068. }
  3069. const_ne_iterator erase(const_ne_iterator f, const_ne_iterator l)
  3070. {
  3071. size_t diff = l - f;
  3072. while (diff--)
  3073. f = erase(f);
  3074. return f;
  3075. }
  3076. // We support reading and writing tables to disk. We don't store
  3077. // the actual array contents (which we don't know how to store),
  3078. // just the groups and sizes. Returns true if all went ok.
  3079. private:
  3080. // Every time the disk format changes, this should probably change too
  3081. typedef unsigned long MagicNumberType;
  3082. static const MagicNumberType MAGIC_NUMBER = 0x24687531;
  3083. // Old versions of this code write all data in 32 bits. We need to
  3084. // support these files as well as having support for 64-bit systems.
  3085. // So we use the following encoding scheme: for values < 2^32-1, we
  3086. // store in 4 bytes in big-endian order. For values > 2^32, we
  3087. // store 0xFFFFFFF followed by 8 bytes in big-endian order. This
  3088. // causes us to mis-read old-version code that stores exactly
  3089. // 0xFFFFFFF, but I don't think that is likely to have happened for
  3090. // these particular values.
  3091. template <typename OUTPUT, typename IntType>
  3092. static bool write_32_or_64(OUTPUT* fp, IntType value)
  3093. {
  3094. if (value < 0xFFFFFFFFULL) { // fits in 4 bytes
  3095. if (!sparsehash_internal::write_bigendian_number(fp, value, 4))
  3096. return false;
  3097. }
  3098. else
  3099. {
  3100. if (!sparsehash_internal::write_bigendian_number(fp, 0xFFFFFFFFUL, 4))
  3101. return false;
  3102. if (!sparsehash_internal::write_bigendian_number(fp, value, 8))
  3103. return false;
  3104. }
  3105. return true;
  3106. }
  3107. template <typename INPUT, typename IntType>
  3108. static bool read_32_or_64(INPUT* fp, IntType *value)
  3109. { // reads into value
  3110. MagicNumberType first4 = 0; // a convenient 32-bit unsigned type
  3111. if (!sparsehash_internal::read_bigendian_number(fp, &first4, 4))
  3112. return false;
  3113. if (first4 < 0xFFFFFFFFULL)
  3114. {
  3115. *value = first4;
  3116. }
  3117. else
  3118. {
  3119. if (!sparsehash_internal::read_bigendian_number(fp, value, 8))
  3120. return false;
  3121. }
  3122. return true;
  3123. }
  3124. public:
  3125. // read/write_metadata() and read_write/nopointer_data() are DEPRECATED.
  3126. // Use serialize() and unserialize(), below, for new code.
  3127. template <typename OUTPUT>
  3128. bool write_metadata(OUTPUT *fp) const
  3129. {
  3130. if (!write_32_or_64(fp, MAGIC_NUMBER)) return false;
  3131. if (!write_32_or_64(fp, _table_size)) return false;
  3132. if (!write_32_or_64(fp, _num_buckets)) return false;
  3133. for (const group_type *group = _first_group; group != _last_group; ++group)
  3134. if (group->write_metadata(fp) == false)
  3135. return false;
  3136. return true;
  3137. }
  3138. // Reading destroys the old table contents! Returns true if read ok.
  3139. template <typename INPUT>
  3140. bool read_metadata(INPUT *fp)
  3141. {
  3142. size_type magic_read = 0;
  3143. if (!read_32_or_64(fp, &magic_read)) return false;
  3144. if (magic_read != MAGIC_NUMBER)
  3145. {
  3146. clear(); // just to be consistent
  3147. return false;
  3148. }
  3149. if (!read_32_or_64(fp, &_table_size)) return false;
  3150. if (!read_32_or_64(fp, &_num_buckets)) return false;
  3151. resize(_table_size); // so the vector's sized ok
  3152. for (group_type *group = _first_group; group != _last_group; ++group)
  3153. if (group->read_metadata(_alloc, fp) == false)
  3154. return false;
  3155. return true;
  3156. }
  3157. // This code is identical to that for SparseGroup
  3158. // If your keys and values are simple enough, we can write them
  3159. // to disk for you. "simple enough" means no pointers.
  3160. // However, we don't try to normalize endianness
  3161. bool write_nopointer_data(FILE *fp) const
  3162. {
  3163. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3164. if (!fwrite(&*it, sizeof(*it), 1, fp))
  3165. return false;
  3166. return true;
  3167. }
  3168. // When reading, we have to override the potential const-ness of *it
  3169. bool read_nopointer_data(FILE *fp)
  3170. {
  3171. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3172. if (!fread(reinterpret_cast<void*>(&(*it)), sizeof(*it), 1, fp))
  3173. return false;
  3174. return true;
  3175. }
  3176. // INPUT and OUTPUT must be either a FILE, *or* a C++ stream
  3177. // (istream, ostream, etc) *or* a class providing
  3178. // Read(void*, size_t) and Write(const void*, size_t)
  3179. // (respectively), which writes a buffer into a stream
  3180. // (which the INPUT/OUTPUT instance presumably owns).
  3181. typedef sparsehash_internal::pod_serializer<value_type> NopointerSerializer;
  3182. // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&)
  3183. template <typename ValueSerializer, typename OUTPUT>
  3184. bool serialize(ValueSerializer serializer, OUTPUT *fp)
  3185. {
  3186. if (!write_metadata(fp))
  3187. return false;
  3188. for (const_ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3189. if (!serializer(fp, *it))
  3190. return false;
  3191. return true;
  3192. }
  3193. // ValueSerializer: a functor. operator()(INPUT*, value_type*)
  3194. template <typename ValueSerializer, typename INPUT>
  3195. bool unserialize(ValueSerializer serializer, INPUT *fp)
  3196. {
  3197. clear();
  3198. if (!read_metadata(fp))
  3199. return false;
  3200. for (ne_iterator it = ne_begin(); it != ne_end(); ++it)
  3201. if (!serializer(fp, &*it))
  3202. return false;
  3203. return true;
  3204. }
  3205. // Comparisons. Note the comparisons are pretty arbitrary: we
  3206. // compare values of the first index that isn't equal (using default
  3207. // value for empty buckets).
  3208. bool operator==(const sparsetable& x) const
  3209. {
  3210. return (_table_size == x._table_size &&
  3211. _num_buckets == x._num_buckets &&
  3212. _first_group == x._first_group);
  3213. }
  3214. bool operator<(const sparsetable& x) const
  3215. {
  3216. return std::lexicographical_compare(begin(), end(), x.begin(), x.end());
  3217. }
  3218. bool operator!=(const sparsetable& x) const { return !(*this == x); }
  3219. bool operator<=(const sparsetable& x) const { return !(x < *this); }
  3220. bool operator>(const sparsetable& x) const { return x < *this; }
  3221. bool operator>=(const sparsetable& x) const { return !(*this < x); }
  3222. private:
  3223. // The actual data
  3224. // ---------------
  3225. group_type * _first_group;
  3226. group_type * _last_group;
  3227. size_type _table_size; // how many buckets they want
  3228. size_type _num_buckets; // number of non-empty buckets
  3229. group_alloc_type _group_alloc;
  3230. value_alloc_type _alloc;
  3231. };
  3232. // We need a global swap as well
  3233. // ---------------------------------------------------------------------------
  3234. template <class T, class Alloc>
  3235. inline void swap(sparsetable<T,Alloc> &x, sparsetable<T,Alloc> &y)
  3236. {
  3237. x.swap(y);
  3238. }
  3239. // ----------------------------------------------------------------------
  3240. // S P A R S E _ H A S H T A B L E
  3241. // ----------------------------------------------------------------------
  3242. // Hashtable class, used to implement the hashed associative containers
  3243. // hash_set and hash_map.
  3244. //
  3245. // Value: what is stored in the table (each bucket is a Value).
  3246. // Key: something in a 1-to-1 correspondence to a Value, that can be used
  3247. // to search for a Value in the table (find() takes a Key).
  3248. // HashFcn: Takes a Key and returns an integer, the more unique the better.
  3249. // ExtractKey: given a Value, returns the unique Key associated with it.
  3250. // Must inherit from unary_function, or at least have a
  3251. // result_type enum indicating the return type of operator().
  3252. // EqualKey: Given two Keys, says whether they are the same (that is,
  3253. // if they are both associated with the same Value).
  3254. // Alloc: STL allocator to use to allocate memory.
  3255. //
  3256. // ----------------------------------------------------------------------
  3257. // The probing method
  3258. // ------------------
  3259. // Linear probing
  3260. // #define JUMP_(key, num_probes) ( 1 )
  3261. // Quadratic probing
  3262. #define JUMP_(key, num_probes) ( num_probes )
  3263. // -------------------------------------------------------------------
  3264. // -------------------------------------------------------------------
  3265. template <class Value, class Key, class HashFcn,
  3266. class ExtractKey, class SetKey, class EqualKey, class Alloc>
  3267. class sparse_hashtable
  3268. {
  3269. private:
  3270. typedef Value mutable_value_type;
  3271. typedef typename Alloc::template rebind<Value>::other value_alloc_type;
  3272. public:
  3273. typedef Key key_type;
  3274. typedef typename spp::cvt<Value>::type value_type;
  3275. typedef HashFcn hasher;
  3276. typedef EqualKey key_equal;
  3277. typedef Alloc allocator_type;
  3278. typedef typename value_alloc_type::size_type size_type;
  3279. typedef typename value_alloc_type::difference_type difference_type;
  3280. typedef value_type& reference;
  3281. typedef const value_type& const_reference;
  3282. typedef value_type* pointer;
  3283. typedef const value_type* const_pointer;
  3284. // Table is the main storage class.
  3285. typedef sparsetable<mutable_value_type, value_alloc_type> Table;
  3286. typedef typename Table::ne_iterator ne_it;
  3287. typedef typename Table::const_ne_iterator cne_it;
  3288. typedef typename Table::destructive_iterator dest_it;
  3289. typedef typename Table::ColIterator ColIterator;
  3290. typedef ne_it iterator;
  3291. typedef cne_it const_iterator;
  3292. typedef dest_it destructive_iterator;
  3293. // These come from tr1. For us they're the same as regular iterators.
  3294. // -------------------------------------------------------------------
  3295. typedef iterator local_iterator;
  3296. typedef const_iterator const_local_iterator;
  3297. // How full we let the table get before we resize
  3298. // ----------------------------------------------
  3299. static const int HT_OCCUPANCY_PCT; // = 80 (out of 100);
  3300. // How empty we let the table get before we resize lower, by default.
  3301. // (0.0 means never resize lower.)
  3302. // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing
  3303. // ------------------------------------------------------------------
  3304. static const int HT_EMPTY_PCT; // = 0.4 * HT_OCCUPANCY_PCT;
  3305. // Minimum size we're willing to let hashtables be.
  3306. // Must be a power of two, and at least 4.
  3307. // Note, however, that for a given hashtable, the initial size is a
  3308. // function of the first constructor arg, and may be >HT_MIN_BUCKETS.
  3309. // ------------------------------------------------------------------
  3310. static const size_type HT_MIN_BUCKETS = 4;
  3311. // By default, if you don't specify a hashtable size at
  3312. // construction-time, we use this size. Must be a power of two, and
  3313. // at least HT_MIN_BUCKETS.
  3314. // -----------------------------------------------------------------
  3315. static const size_type HT_DEFAULT_STARTING_BUCKETS = 32;
  3316. // iterators
  3317. // ---------
  3318. iterator begin() { return _mk_iterator(table.ne_begin()); }
  3319. iterator end() { return _mk_iterator(table.ne_end()); }
  3320. const_iterator begin() const { return _mk_const_iterator(table.ne_cbegin()); }
  3321. const_iterator end() const { return _mk_const_iterator(table.ne_cend()); }
  3322. const_iterator cbegin() const { return _mk_const_iterator(table.ne_cbegin()); }
  3323. const_iterator cend() const { return _mk_const_iterator(table.ne_cend()); }
  3324. // These come from tr1 unordered_map. They iterate over 'bucket' n.
  3325. // For sparsehashtable, we could consider each 'group' to be a bucket,
  3326. // I guess, but I don't really see the point. We'll just consider
  3327. // bucket n to be the n-th element of the sparsetable, if it's occupied,
  3328. // or some empty element, otherwise.
  3329. // ---------------------------------------------------------------------
  3330. local_iterator begin(size_type i)
  3331. {
  3332. return _mk_iterator(table.test(i) ? table.get_iter(i) : table.ne_end());
  3333. }
  3334. local_iterator end(size_type i)
  3335. {
  3336. local_iterator it = begin(i);
  3337. if (table.test(i))
  3338. ++it;
  3339. return _mk_iterator(it);
  3340. }
  3341. const_local_iterator begin(size_type i) const
  3342. {
  3343. return _mk_const_iterator(table.test(i) ? table.get_iter(i) : table.ne_cend());
  3344. }
  3345. const_local_iterator end(size_type i) const
  3346. {
  3347. const_local_iterator it = begin(i);
  3348. if (table.test(i))
  3349. ++it;
  3350. return _mk_const_iterator(it);
  3351. }
  3352. const_local_iterator cbegin(size_type i) const { return begin(i); }
  3353. const_local_iterator cend(size_type i) const { return end(i); }
  3354. // This is used when resizing
  3355. // --------------------------
  3356. destructive_iterator destructive_begin() { return _mk_destructive_iterator(table.destructive_begin()); }
  3357. destructive_iterator destructive_end() { return _mk_destructive_iterator(table.destructive_end()); }
  3358. // accessor functions for the things we templatize on, basically
  3359. // -------------------------------------------------------------
  3360. hasher hash_funct() const { return settings; }
  3361. key_equal key_eq() const { return key_info; }
  3362. allocator_type get_allocator() const { return table.get_allocator(); }
  3363. // Accessor function for statistics gathering.
  3364. unsigned int num_table_copies() const { return settings.num_ht_copies(); }
  3365. private:
  3366. // This is used as a tag for the copy constructor, saying to destroy its
  3367. // arg We have two ways of destructively copying: with potentially growing
  3368. // the hashtable as we copy, and without. To make sure the outside world
  3369. // can't do a destructive copy, we make the typename private.
  3370. // -----------------------------------------------------------------------
  3371. enum MoveDontCopyT {MoveDontCopy, MoveDontGrow};
  3372. void _squash_deleted()
  3373. {
  3374. // gets rid of any deleted entries we have
  3375. // ---------------------------------------
  3376. if (num_deleted)
  3377. {
  3378. // get rid of deleted before writing
  3379. sparse_hashtable tmp(MoveDontGrow, *this);
  3380. swap(tmp); // now we are tmp
  3381. }
  3382. assert(num_deleted == 0);
  3383. }
  3384. // creating iterators from sparsetable::ne_iterators
  3385. // -------------------------------------------------
  3386. iterator _mk_iterator(ne_it it) const { return it; }
  3387. const_iterator _mk_const_iterator(cne_it it) const { return it; }
  3388. destructive_iterator _mk_destructive_iterator(dest_it it) const { return it; }
  3389. public:
  3390. size_type size() const { return table.num_nonempty(); }
  3391. size_type max_size() const { return table.max_size(); }
  3392. bool empty() const { return size() == 0; }
  3393. size_type bucket_count() const { return table.size(); }
  3394. size_type max_bucket_count() const { return max_size(); }
  3395. // These are tr1 methods. Their idea of 'bucket' doesn't map well to
  3396. // what we do. We just say every bucket has 0 or 1 items in it.
  3397. size_type bucket_size(size_type i) const
  3398. {
  3399. return (size_type)(begin(i) == end(i) ? 0 : 1);
  3400. }
  3401. private:
  3402. // Because of the above, size_type(-1) is never legal; use it for errors
  3403. // ---------------------------------------------------------------------
  3404. static const size_type ILLEGAL_BUCKET = size_type(-1);
  3405. // Used after a string of deletes. Returns true if we actually shrunk.
  3406. // TODO(csilvers): take a delta so we can take into account inserts
  3407. // done after shrinking. Maybe make part of the Settings class?
  3408. // --------------------------------------------------------------------
  3409. bool _maybe_shrink()
  3410. {
  3411. assert((bucket_count() & (bucket_count()-1)) == 0); // is a power of two
  3412. assert(bucket_count() >= HT_MIN_BUCKETS);
  3413. bool retval = false;
  3414. // If you construct a hashtable with < HT_DEFAULT_STARTING_BUCKETS,
  3415. // we'll never shrink until you get relatively big, and we'll never
  3416. // shrink below HT_DEFAULT_STARTING_BUCKETS. Otherwise, something
  3417. // like "dense_hash_set<int> x; x.insert(4); x.erase(4);" will
  3418. // shrink us down to HT_MIN_BUCKETS buckets, which is too small.
  3419. // ---------------------------------------------------------------
  3420. const size_type num_remain = table.num_nonempty();
  3421. const size_type shrink_threshold = settings.shrink_threshold();
  3422. if (shrink_threshold > 0 && num_remain < shrink_threshold &&
  3423. bucket_count() > HT_DEFAULT_STARTING_BUCKETS)
  3424. {
  3425. const float shrink_factor = settings.shrink_factor();
  3426. size_type sz = (size_type)(bucket_count() / 2); // find how much we should shrink
  3427. while (sz > HT_DEFAULT_STARTING_BUCKETS &&
  3428. num_remain < static_cast<size_type>(sz * shrink_factor))
  3429. {
  3430. sz /= 2; // stay a power of 2
  3431. }
  3432. sparse_hashtable tmp(MoveDontCopy, *this, sz);
  3433. swap(tmp); // now we are tmp
  3434. retval = true;
  3435. }
  3436. settings.set_consider_shrink(false); // because we just considered it
  3437. return retval;
  3438. }
  3439. // We'll let you resize a hashtable -- though this makes us copy all!
  3440. // When you resize, you say, "make it big enough for this many more elements"
  3441. // Returns true if we actually resized, false if size was already ok.
  3442. // --------------------------------------------------------------------------
  3443. bool _resize_delta(size_type delta)
  3444. {
  3445. bool did_resize = false;
  3446. if (settings.consider_shrink())
  3447. {
  3448. // see if lots of deletes happened
  3449. if (_maybe_shrink())
  3450. did_resize = true;
  3451. }
  3452. if (table.num_nonempty() >=
  3453. (std::numeric_limits<size_type>::max)() - delta)
  3454. {
  3455. throw_exception(std::length_error("resize overflow"));
  3456. }
  3457. size_type num_occupied = (size_type)(table.num_nonempty() + num_deleted);
  3458. if (bucket_count() >= HT_MIN_BUCKETS &&
  3459. (num_occupied + delta) <= settings.enlarge_threshold())
  3460. return did_resize; // we're ok as we are
  3461. // Sometimes, we need to resize just to get rid of all the
  3462. // "deleted" buckets that are clogging up the hashtable. So when
  3463. // deciding whether to resize, count the deleted buckets (which
  3464. // are currently taking up room).
  3465. // -------------------------------------------------------------
  3466. const size_type needed_size =
  3467. settings.min_buckets((size_type)(num_occupied + delta), (size_type)0);
  3468. if (needed_size <= bucket_count()) // we have enough buckets
  3469. return did_resize;
  3470. size_type resize_to = settings.min_buckets((size_type)(num_occupied + delta), bucket_count());
  3471. if (resize_to < needed_size && // may double resize_to
  3472. resize_to < (std::numeric_limits<size_type>::max)() / 2)
  3473. {
  3474. // This situation means that we have enough deleted elements,
  3475. // that once we purge them, we won't actually have needed to
  3476. // grow. But we may want to grow anyway: if we just purge one
  3477. // element, say, we'll have to grow anyway next time we
  3478. // insert. Might as well grow now, since we're already going
  3479. // through the trouble of copying (in order to purge the
  3480. // deleted elements).
  3481. const size_type target =
  3482. static_cast<size_type>(settings.shrink_size((size_type)(resize_to*2)));
  3483. if (table.num_nonempty() + delta >= target)
  3484. {
  3485. // Good, we won't be below the shrink threshhold even if we double.
  3486. resize_to *= 2;
  3487. }
  3488. }
  3489. sparse_hashtable tmp(MoveDontCopy, *this, resize_to);
  3490. swap(tmp); // now we are tmp
  3491. return true;
  3492. }
  3493. // Used to actually do the rehashing when we grow/shrink a hashtable
  3494. // -----------------------------------------------------------------
  3495. void _copy_from(const sparse_hashtable &ht, size_type min_buckets_wanted)
  3496. {
  3497. clear(); // clear table, set num_deleted to 0
  3498. // If we need to change the size of our table, do it now
  3499. const size_type resize_to = settings.min_buckets(ht.size(), min_buckets_wanted);
  3500. if (resize_to > bucket_count())
  3501. {
  3502. // we don't have enough buckets
  3503. table.resize(resize_to); // sets the number of buckets
  3504. settings.reset_thresholds(bucket_count());
  3505. }
  3506. // We use a normal iterator to get bcks from ht
  3507. // We could use insert() here, but since we know there are
  3508. // no duplicates, we can be more efficient
  3509. assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
  3510. for (const_iterator it = ht.begin(); it != ht.end(); ++it)
  3511. {
  3512. size_type num_probes = 0; // how many times we've probed
  3513. size_type bucknum;
  3514. const size_type bucket_count_minus_one = bucket_count() - 1;
  3515. for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
  3516. table.test(bucknum); // table.test() OK since no erase()
  3517. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one)
  3518. {
  3519. ++num_probes;
  3520. assert(num_probes < bucket_count()
  3521. && "Hashtable is full: an error in key_equal<> or hash<>");
  3522. }
  3523. table.set(bucknum, *it, false); // copies the value to here
  3524. }
  3525. settings.inc_num_ht_copies();
  3526. }
  3527. // Implementation is like _copy_from, but it destroys the table of the
  3528. // "from" guy by freeing sparsetable memory as we iterate. This is
  3529. // useful in resizing, since we're throwing away the "from" guy anyway.
  3530. // --------------------------------------------------------------------
  3531. void _move_from(MoveDontCopyT mover, sparse_hashtable &ht,
  3532. size_type min_buckets_wanted)
  3533. {
  3534. clear();
  3535. // If we need to change the size of our table, do it now
  3536. size_type resize_to;
  3537. if (mover == MoveDontGrow)
  3538. resize_to = ht.bucket_count(); // keep same size as old ht
  3539. else // MoveDontCopy
  3540. resize_to = settings.min_buckets(ht.size(), min_buckets_wanted);
  3541. if (resize_to > bucket_count())
  3542. {
  3543. // we don't have enough buckets
  3544. table.resize(resize_to); // sets the number of buckets
  3545. settings.reset_thresholds(bucket_count());
  3546. }
  3547. // We use a normal iterator to get bcks from ht
  3548. // We could use insert() here, but since we know there are
  3549. // no duplicates, we can be more efficient
  3550. assert((bucket_count() & (bucket_count()-1)) == 0); // a power of two
  3551. const size_type bucket_count_minus_one = (const size_type)(bucket_count() - 1);
  3552. // THIS IS THE MAJOR LINE THAT DIFFERS FROM COPY_FROM():
  3553. for (destructive_iterator it = ht.destructive_begin();
  3554. it != ht.destructive_end(); ++it)
  3555. {
  3556. size_type num_probes = 0;
  3557. size_type bucknum;
  3558. for (bucknum = hash(get_key(*it)) & bucket_count_minus_one;
  3559. table.test(bucknum); // table.test() OK since no erase()
  3560. bucknum = (size_type)((bucknum + JUMP_(key, num_probes)) & (bucket_count()-1)))
  3561. {
  3562. ++num_probes;
  3563. assert(num_probes < bucket_count()
  3564. && "Hashtable is full: an error in key_equal<> or hash<>");
  3565. }
  3566. table.move(bucknum, *it); // moves the value to here
  3567. }
  3568. settings.inc_num_ht_copies();
  3569. }
  3570. // Required by the spec for hashed associative container
  3571. public:
  3572. // Though the docs say this should be num_buckets, I think it's much
  3573. // more useful as num_elements. As a special feature, calling with
  3574. // req_elements==0 will cause us to shrink if we can, saving space.
  3575. // -----------------------------------------------------------------
  3576. void resize(size_type req_elements)
  3577. {
  3578. // resize to this or larger
  3579. if (settings.consider_shrink() || req_elements == 0)
  3580. _maybe_shrink();
  3581. if (req_elements > table.num_nonempty()) // we only grow
  3582. _resize_delta((size_type)(req_elements - table.num_nonempty()));
  3583. }
  3584. // Get and change the value of shrink_factor and enlarge_factor. The
  3585. // description at the beginning of this file explains how to choose
  3586. // the values. Setting the shrink parameter to 0.0 ensures that the
  3587. // table never shrinks.
  3588. // ------------------------------------------------------------------
  3589. void get_resizing_parameters(float* shrink, float* grow) const
  3590. {
  3591. *shrink = settings.shrink_factor();
  3592. *grow = settings.enlarge_factor();
  3593. }
  3594. float get_shrink_factor() const { return settings.shrink_factor(); }
  3595. float get_enlarge_factor() const { return settings.enlarge_factor(); }
  3596. void set_resizing_parameters(float shrink, float grow) {
  3597. settings.set_resizing_parameters(shrink, grow);
  3598. settings.reset_thresholds(bucket_count());
  3599. }
  3600. void set_shrink_factor(float shrink)
  3601. {
  3602. set_resizing_parameters(shrink, get_enlarge_factor());
  3603. }
  3604. void set_enlarge_factor(float grow)
  3605. {
  3606. set_resizing_parameters(get_shrink_factor(), grow);
  3607. }
  3608. // CONSTRUCTORS -- as required by the specs, we take a size,
  3609. // but also let you specify a hashfunction, key comparator,
  3610. // and key extractor. We also define a copy constructor and =.
  3611. // DESTRUCTOR -- the default is fine, surprisingly.
  3612. // ------------------------------------------------------------
  3613. explicit sparse_hashtable(size_type expected_max_items_in_table = 0,
  3614. const HashFcn& hf = HashFcn(),
  3615. const EqualKey& eql = EqualKey(),
  3616. const ExtractKey& ext = ExtractKey(),
  3617. const SetKey& set = SetKey(),
  3618. const Alloc& alloc = Alloc())
  3619. : settings(hf),
  3620. key_info(ext, set, eql),
  3621. num_deleted(0),
  3622. table((expected_max_items_in_table == 0
  3623. ? HT_DEFAULT_STARTING_BUCKETS
  3624. : settings.min_buckets(expected_max_items_in_table, 0)),
  3625. value_alloc_type(alloc))
  3626. {
  3627. settings.reset_thresholds(bucket_count());
  3628. }
  3629. // As a convenience for resize(), we allow an optional second argument
  3630. // which lets you make this new hashtable a different size than ht.
  3631. // We also provide a mechanism of saying you want to "move" the ht argument
  3632. // into us instead of copying.
  3633. // ------------------------------------------------------------------------
  3634. sparse_hashtable(const sparse_hashtable& ht,
  3635. size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
  3636. : settings(ht.settings),
  3637. key_info(ht.key_info),
  3638. num_deleted(0),
  3639. table(0)
  3640. {
  3641. settings.reset_thresholds(bucket_count());
  3642. _copy_from(ht, min_buckets_wanted);
  3643. }
  3644. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  3645. sparse_hashtable(sparse_hashtable&& o) :
  3646. settings(std::move(o.settings)),
  3647. key_info(std::move(o.key_info)),
  3648. num_deleted(o.num_deleted),
  3649. table(std::move(o.table))
  3650. {
  3651. }
  3652. sparse_hashtable(sparse_hashtable&& o, const Alloc& alloc) :
  3653. settings(std::move(o.settings)),
  3654. key_info(std::move(o.key_info)),
  3655. num_deleted(o.num_deleted),
  3656. table(std::move(o.table), alloc)
  3657. {
  3658. }
  3659. sparse_hashtable& operator=(sparse_hashtable&& o)
  3660. {
  3661. using std::swap;
  3662. sparse_hashtable tmp(std::move(o));
  3663. swap(tmp, *this);
  3664. return *this;
  3665. }
  3666. #endif
  3667. sparse_hashtable(MoveDontCopyT mover,
  3668. sparse_hashtable& ht,
  3669. size_type min_buckets_wanted = HT_DEFAULT_STARTING_BUCKETS)
  3670. : settings(ht.settings),
  3671. key_info(ht.key_info),
  3672. num_deleted(0),
  3673. table(min_buckets_wanted, ht.table.get_allocator())
  3674. {
  3675. settings.reset_thresholds(bucket_count());
  3676. _move_from(mover, ht, min_buckets_wanted);
  3677. }
  3678. sparse_hashtable& operator=(const sparse_hashtable& ht)
  3679. {
  3680. if (&ht == this)
  3681. return *this; // don't copy onto ourselves
  3682. settings = ht.settings;
  3683. key_info = ht.key_info;
  3684. num_deleted = ht.num_deleted;
  3685. // _copy_from() calls clear and sets num_deleted to 0 too
  3686. _copy_from(ht, HT_MIN_BUCKETS);
  3687. // we purposefully don't copy the allocator, which may not be copyable
  3688. return *this;
  3689. }
  3690. // Many STL algorithms use swap instead of copy constructors
  3691. void swap(sparse_hashtable& ht)
  3692. {
  3693. using std::swap;
  3694. swap(settings, ht.settings);
  3695. swap(key_info, ht.key_info);
  3696. swap(num_deleted, ht.num_deleted);
  3697. table.swap(ht.table);
  3698. settings.reset_thresholds(bucket_count()); // also resets consider_shrink
  3699. ht.settings.reset_thresholds(ht.bucket_count());
  3700. // we purposefully don't swap the allocator, which may not be swap-able
  3701. }
  3702. // It's always nice to be able to clear a table without deallocating it
  3703. void clear()
  3704. {
  3705. if (!empty() || num_deleted != 0)
  3706. {
  3707. table.clear();
  3708. table = Table(HT_DEFAULT_STARTING_BUCKETS);
  3709. }
  3710. settings.reset_thresholds(bucket_count());
  3711. num_deleted = 0;
  3712. }
  3713. // LOOKUP ROUTINES
  3714. private:
  3715. enum pos_type { pt_empty = 0, pt_erased, pt_full };
  3716. // -------------------------------------------------------------------
  3717. class Position
  3718. {
  3719. public:
  3720. Position() : _t(pt_empty) {}
  3721. Position(pos_type t, size_type idx) : _t(t), _idx(idx) {}
  3722. pos_type _t;
  3723. size_type _idx;
  3724. };
  3725. // Returns a pair:
  3726. // - 'first' is a code, 2 if key already present, 0 or 1 otherwise.
  3727. // - 'second' is a position, where the key should go
  3728. // Note: because of deletions where-to-insert is not trivial: it's the
  3729. // first deleted bucket we see, as long as we don't find the key later
  3730. // -------------------------------------------------------------------
  3731. Position _find_position(const key_type &key) const
  3732. {
  3733. size_type num_probes = 0; // how many times we've probed
  3734. const size_type bucket_count_minus_one = (const size_type)(bucket_count() - 1);
  3735. size_type bucknum = hash(key) & bucket_count_minus_one;
  3736. Position pos;
  3737. while (1)
  3738. {
  3739. // probe until something happens
  3740. // -----------------------------
  3741. typename Table::GrpPos grp_pos(table, bucknum);
  3742. if (!grp_pos.test_strict())
  3743. {
  3744. // bucket is empty => key not present
  3745. return pos._t ? pos : Position(pt_empty, bucknum);
  3746. }
  3747. else if (grp_pos.test())
  3748. {
  3749. reference ref(grp_pos.unsafe_get());
  3750. if (equals(key, get_key(ref)))
  3751. return Position(pt_full, bucknum);
  3752. }
  3753. else if (pos._t == pt_empty)
  3754. {
  3755. // first erased position
  3756. pos._t = pt_erased;
  3757. pos._idx = bucknum;
  3758. }
  3759. ++num_probes; // we're doing another probe
  3760. bucknum = (size_type)((bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one);
  3761. assert(num_probes < bucket_count()
  3762. && "Hashtable is full: an error in key_equal<> or hash<>");
  3763. }
  3764. }
  3765. public:
  3766. // I hate to duplicate find() like that, but it is
  3767. // significantly faster to not have the intermediate pair
  3768. // ------------------------------------------------------------------
  3769. iterator find(const key_type& key)
  3770. {
  3771. size_type num_probes = 0; // how many times we've probed
  3772. const size_type bucket_count_minus_one = bucket_count() - 1;
  3773. size_type bucknum = hash(key) & bucket_count_minus_one;
  3774. while (1) // probe until something happens
  3775. {
  3776. typename Table::GrpPos grp_pos(table, bucknum);
  3777. if (!grp_pos.test_strict())
  3778. return end(); // bucket is empty
  3779. if (grp_pos.test())
  3780. {
  3781. reference ref(grp_pos.unsafe_get());
  3782. if (equals(key, get_key(ref)))
  3783. return grp_pos.get_iter(ref);
  3784. }
  3785. ++num_probes; // we're doing another probe
  3786. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3787. assert(num_probes < bucket_count()
  3788. && "Hashtable is full: an error in key_equal<> or hash<>");
  3789. }
  3790. }
  3791. // Wish I could avoid the duplicate find() const and non-const.
  3792. // ------------------------------------------------------------
  3793. const_iterator find(const key_type& key) const
  3794. {
  3795. size_type num_probes = 0; // how many times we've probed
  3796. const size_type bucket_count_minus_one = bucket_count() - 1;
  3797. size_type bucknum = hash(key) & bucket_count_minus_one;
  3798. while (1) // probe until something happens
  3799. {
  3800. typename Table::GrpPos grp_pos(table, bucknum);
  3801. if (!grp_pos.test_strict())
  3802. return end(); // bucket is empty
  3803. else if (grp_pos.test())
  3804. {
  3805. reference ref(grp_pos.unsafe_get());
  3806. if (equals(key, get_key(ref)))
  3807. return _mk_const_iterator(table.get_iter(bucknum, &ref));
  3808. }
  3809. ++num_probes; // we're doing another probe
  3810. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3811. assert(num_probes < bucket_count()
  3812. && "Hashtable is full: an error in key_equal<> or hash<>");
  3813. }
  3814. }
  3815. // This is a tr1 method: the bucket a given key is in, or what bucket
  3816. // it would be put in, if it were to be inserted. Shrug.
  3817. // ------------------------------------------------------------------
  3818. size_type bucket(const key_type& key) const
  3819. {
  3820. Position pos = _find_position(key);
  3821. return pos._idx;
  3822. }
  3823. // Counts how many elements have key key. For maps, it's either 0 or 1.
  3824. // ---------------------------------------------------------------------
  3825. size_type count(const key_type &key) const
  3826. {
  3827. Position pos = _find_position(key);
  3828. return (size_type)(pos._t == pt_full ? 1 : 0);
  3829. }
  3830. // Likewise, equal_range doesn't really make sense for us. Oh well.
  3831. // -----------------------------------------------------------------
  3832. std::pair<iterator,iterator> equal_range(const key_type& key)
  3833. {
  3834. iterator pos = find(key); // either an iterator or end
  3835. if (pos == end())
  3836. return std::pair<iterator,iterator>(pos, pos);
  3837. else
  3838. {
  3839. const iterator startpos = pos++;
  3840. return std::pair<iterator,iterator>(startpos, pos);
  3841. }
  3842. }
  3843. std::pair<const_iterator,const_iterator> equal_range(const key_type& key) const
  3844. {
  3845. const_iterator pos = find(key); // either an iterator or end
  3846. if (pos == end())
  3847. return std::pair<const_iterator,const_iterator>(pos, pos);
  3848. else
  3849. {
  3850. const const_iterator startpos = pos++;
  3851. return std::pair<const_iterator,const_iterator>(startpos, pos);
  3852. }
  3853. }
  3854. // INSERTION ROUTINES
  3855. private:
  3856. // Private method used by insert_noresize and find_or_insert.
  3857. reference _insert_at(const_reference obj, size_type pos, bool erased)
  3858. {
  3859. if (size() >= max_size())
  3860. {
  3861. throw_exception(std::length_error("insert overflow"));
  3862. }
  3863. if (erased)
  3864. {
  3865. assert(num_deleted);
  3866. --num_deleted;
  3867. }
  3868. return table.set(pos, obj, erased);
  3869. }
  3870. // If you know *this is big enough to hold obj, use this routine
  3871. std::pair<iterator, bool> _insert_noresize(const_reference obj)
  3872. {
  3873. Position pos = _find_position(get_key(obj));
  3874. bool already_there = (pos._t == pt_full);
  3875. if (!already_there)
  3876. {
  3877. reference ref(_insert_at(obj, pos._idx, pos._t == pt_erased));
  3878. return std::pair<iterator, bool>(_mk_iterator(table.get_iter(pos._idx, &ref)), true);
  3879. }
  3880. return std::pair<iterator,bool>(_mk_iterator(table.get_iter(pos._idx)), false);
  3881. }
  3882. // Specializations of insert(it, it) depending on the power of the iterator:
  3883. // (1) Iterator supports operator-, resize before inserting
  3884. template <class ForwardIterator>
  3885. void _insert(ForwardIterator f, ForwardIterator l, std::forward_iterator_tag /*unused*/)
  3886. {
  3887. int64_t dist = std::distance(f, l);
  3888. if (dist < 0 || static_cast<size_t>(dist) >= (std::numeric_limits<size_type>::max)())
  3889. throw_exception(std::length_error("insert-range overflow"));
  3890. _resize_delta(static_cast<size_type>(dist));
  3891. for (; dist > 0; --dist, ++f)
  3892. _insert_noresize(*f);
  3893. }
  3894. // (2) Arbitrary iterator, can't tell how much to resize
  3895. template <class InputIterator>
  3896. void _insert(InputIterator f, InputIterator l, std::input_iterator_tag /*unused*/)
  3897. {
  3898. for (; f != l; ++f)
  3899. _insert(*f);
  3900. }
  3901. public:
  3902. #if 0 && !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)
  3903. template <class... Args>
  3904. pair<iterator, bool> emplace(Args&&... args)
  3905. {
  3906. return rep.emplace_unique(std::forward<Args>(args)...);
  3907. }
  3908. template <class... Args>
  3909. iterator emplace_hint(const_iterator p, Args&&... args)
  3910. {
  3911. return rep.emplace_unique(std::forward<Args>(args)...).first;
  3912. }
  3913. #endif
  3914. // This is the normal insert routine, used by the outside world
  3915. std::pair<iterator, bool> insert(const_reference obj)
  3916. {
  3917. _resize_delta(1); // adding an object, grow if need be
  3918. return _insert_noresize(obj);
  3919. }
  3920. // When inserting a lot at a time, we specialize on the type of iterator
  3921. template <class InputIterator>
  3922. void insert(InputIterator f, InputIterator l)
  3923. {
  3924. // specializes on iterator type
  3925. _insert(f, l,
  3926. typename std::iterator_traits<InputIterator>::iterator_category());
  3927. }
  3928. // DefaultValue is a functor that takes a key and returns a value_type
  3929. // representing the default value to be inserted if none is found.
  3930. template <class DefaultValue>
  3931. value_type& find_or_insert(const key_type& key)
  3932. {
  3933. size_type num_probes = 0; // how many times we've probed
  3934. const size_type bucket_count_minus_one = bucket_count() - 1;
  3935. size_type bucknum = hash(key) & bucket_count_minus_one;
  3936. DefaultValue default_value;
  3937. size_type erased_pos = 0;
  3938. bool erased = false;
  3939. while (1) // probe until something happens
  3940. {
  3941. typename Table::GrpPos grp_pos(table, bucknum);
  3942. if (!grp_pos.test_strict())
  3943. {
  3944. // not found
  3945. if (_resize_delta(1))
  3946. {
  3947. // needed to rehash to make room
  3948. // Since we resized, we can't use pos, so recalculate where to insert.
  3949. return *(_insert_noresize(default_value(key)).first);
  3950. }
  3951. else
  3952. {
  3953. // no need to rehash, insert right here
  3954. return _insert_at(default_value(key), erased ? erased_pos : bucknum, erased);
  3955. }
  3956. }
  3957. if (grp_pos.test())
  3958. {
  3959. reference ref(grp_pos.unsafe_get());
  3960. if (equals(key, get_key(ref)))
  3961. return ref;
  3962. }
  3963. else if (!erased)
  3964. {
  3965. // first erased position
  3966. erased_pos = bucknum;
  3967. erased = true;
  3968. }
  3969. ++num_probes; // we're doing another probe
  3970. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3971. assert(num_probes < bucket_count()
  3972. && "Hashtable is full: an error in key_equal<> or hash<>");
  3973. }
  3974. }
  3975. size_type erase(const key_type& key)
  3976. {
  3977. size_type num_probes = 0; // how many times we've probed
  3978. const size_type bucket_count_minus_one = bucket_count() - 1;
  3979. size_type bucknum = hash(key) & bucket_count_minus_one;
  3980. while (1) // probe until something happens
  3981. {
  3982. typename Table::GrpPos grp_pos(table, bucknum);
  3983. if (!grp_pos.test_strict())
  3984. return 0; // bucket is empty, we deleted nothing
  3985. if (grp_pos.test())
  3986. {
  3987. reference ref(grp_pos.unsafe_get());
  3988. if (equals(key, get_key(ref)))
  3989. {
  3990. grp_pos.erase(table);
  3991. ++num_deleted;
  3992. settings.set_consider_shrink(true); // will think about shrink after next insert
  3993. return 1; // because we deleted one thing
  3994. }
  3995. }
  3996. ++num_probes; // we're doing another probe
  3997. bucknum = (bucknum + JUMP_(key, num_probes)) & bucket_count_minus_one;
  3998. assert(num_probes < bucket_count()
  3999. && "Hashtable is full: an error in key_equal<> or hash<>");
  4000. }
  4001. }
  4002. const_iterator erase(const_iterator pos)
  4003. {
  4004. if (pos == cend())
  4005. return cend(); // sanity check
  4006. const_iterator nextpos = table.erase(pos);
  4007. ++num_deleted;
  4008. settings.set_consider_shrink(true);
  4009. return nextpos;
  4010. }
  4011. const_iterator erase(const_iterator f, const_iterator l)
  4012. {
  4013. if (f == cend())
  4014. return cend(); // sanity check
  4015. size_type num_before = table.num_nonempty();
  4016. const_iterator nextpos = table.erase(f, l);
  4017. num_deleted += num_before - table.num_nonempty();
  4018. settings.set_consider_shrink(true);
  4019. return nextpos;
  4020. }
  4021. // Deleted key routines - just to keep google test framework happy
  4022. // we don't actually use the deleted key
  4023. // ---------------------------------------------------------------
  4024. void set_deleted_key(const key_type& key)
  4025. {
  4026. _squash_deleted();
  4027. key_info.delkey = key;
  4028. }
  4029. void clear_deleted_key()
  4030. {
  4031. _squash_deleted();
  4032. }
  4033. key_type deleted_key() const
  4034. {
  4035. return key_info.delkey;
  4036. }
  4037. bool operator==(const sparse_hashtable& ht) const
  4038. {
  4039. if (this == &ht)
  4040. return true;
  4041. if (size() != ht.size())
  4042. return false;
  4043. for (const_iterator it = begin(); it != end(); ++it)
  4044. {
  4045. const_iterator it2 = ht.find(get_key(*it));
  4046. if ((it2 == ht.end()) || (*it != *it2))
  4047. return false;
  4048. }
  4049. return true;
  4050. }
  4051. bool operator!=(const sparse_hashtable& ht) const
  4052. {
  4053. return !(*this == ht);
  4054. }
  4055. // I/O
  4056. // We support reading and writing hashtables to disk. NOTE that
  4057. // this only stores the hashtable metadata, not the stuff you've
  4058. // actually put in the hashtable! Alas, since I don't know how to
  4059. // write a hasher or key_equal, you have to make sure everything
  4060. // but the table is the same. We compact before writing.
  4061. //
  4062. // The OUTPUT type needs to support a Write() operation. File and
  4063. // OutputBuffer are appropriate types to pass in.
  4064. //
  4065. // The INPUT type needs to support a Read() operation. File and
  4066. // InputBuffer are appropriate types to pass in.
  4067. // -------------------------------------------------------------
  4068. template <typename OUTPUT>
  4069. bool write_metadata(OUTPUT *fp)
  4070. {
  4071. _squash_deleted(); // so we don't have to worry about delkey
  4072. return table.write_metadata(fp);
  4073. }
  4074. template <typename INPUT>
  4075. bool read_metadata(INPUT *fp)
  4076. {
  4077. num_deleted = 0; // since we got rid before writing
  4078. const bool result = table.read_metadata(fp);
  4079. settings.reset_thresholds(bucket_count());
  4080. return result;
  4081. }
  4082. // Only meaningful if value_type is a POD.
  4083. template <typename OUTPUT>
  4084. bool write_nopointer_data(OUTPUT *fp)
  4085. {
  4086. return table.write_nopointer_data(fp);
  4087. }
  4088. // Only meaningful if value_type is a POD.
  4089. template <typename INPUT>
  4090. bool read_nopointer_data(INPUT *fp)
  4091. {
  4092. return table.read_nopointer_data(fp);
  4093. }
  4094. // INPUT and OUTPUT must be either a FILE, *or* a C++ stream
  4095. // (istream, ostream, etc) *or* a class providing
  4096. // Read(void*, size_t) and Write(const void*, size_t)
  4097. // (respectively), which writes a buffer into a stream
  4098. // (which the INPUT/OUTPUT instance presumably owns).
  4099. typedef sparsehash_internal::pod_serializer<value_type> NopointerSerializer;
  4100. // ValueSerializer: a functor. operator()(OUTPUT*, const value_type&)
  4101. template <typename ValueSerializer, typename OUTPUT>
  4102. bool serialize(ValueSerializer serializer, OUTPUT *fp)
  4103. {
  4104. _squash_deleted(); // so we don't have to worry about delkey
  4105. return table.serialize(serializer, fp);
  4106. }
  4107. // ValueSerializer: a functor. operator()(INPUT*, value_type*)
  4108. template <typename ValueSerializer, typename INPUT>
  4109. bool unserialize(ValueSerializer serializer, INPUT *fp)
  4110. {
  4111. num_deleted = 0; // since we got rid before writing
  4112. const bool result = table.unserialize(serializer, fp);
  4113. settings.reset_thresholds(bucket_count());
  4114. return result;
  4115. }
  4116. private:
  4117. // Package templated functors with the other types to eliminate memory
  4118. // needed for storing these zero-size operators. Since ExtractKey and
  4119. // hasher's operator() might have the same function signature, they
  4120. // must be packaged in different classes.
  4121. // -------------------------------------------------------------------------
  4122. struct Settings :
  4123. sparsehash_internal::sh_hashtable_settings<key_type, hasher,
  4124. size_type, HT_MIN_BUCKETS>
  4125. {
  4126. explicit Settings(const hasher& hf)
  4127. : sparsehash_internal::sh_hashtable_settings<key_type, hasher, size_type,
  4128. HT_MIN_BUCKETS>
  4129. (hf, HT_OCCUPANCY_PCT / 100.0f, HT_EMPTY_PCT / 100.0f) {}
  4130. };
  4131. // KeyInfo stores delete key and packages zero-size functors:
  4132. // ExtractKey and SetKey.
  4133. // ---------------------------------------------------------
  4134. class KeyInfo : public ExtractKey, public SetKey, public EqualKey
  4135. {
  4136. public:
  4137. KeyInfo(const ExtractKey& ek, const SetKey& sk, const EqualKey& eq)
  4138. : ExtractKey(ek), SetKey(sk), EqualKey(eq)
  4139. {
  4140. }
  4141. // We want to return the exact same type as ExtractKey: Key or const Key&
  4142. typename ExtractKey::result_type get_key(const_reference v) const
  4143. {
  4144. return ExtractKey::operator()(v);
  4145. }
  4146. bool equals(const key_type& a, const key_type& b) const
  4147. {
  4148. return EqualKey::operator()(a, b);
  4149. }
  4150. typename spp_::remove_const<key_type>::type delkey;
  4151. };
  4152. // Utility functions to access the templated operators
  4153. size_t hash(const key_type& v) const
  4154. {
  4155. return settings.hash(v);
  4156. }
  4157. bool equals(const key_type& a, const key_type& b) const
  4158. {
  4159. return key_info.equals(a, b);
  4160. }
  4161. typename ExtractKey::result_type get_key(const_reference v) const
  4162. {
  4163. return key_info.get_key(v);
  4164. }
  4165. private:
  4166. // Actual data
  4167. // -----------
  4168. Settings settings;
  4169. KeyInfo key_info;
  4170. size_type num_deleted;
  4171. Table table; // holds num_buckets and num_elements too
  4172. };
  4173. // We need a global swap as well
  4174. // -----------------------------
  4175. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4176. inline void swap(sparse_hashtable<V,K,HF,ExK,SetK,EqK,A> &x,
  4177. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A> &y)
  4178. {
  4179. x.swap(y);
  4180. }
  4181. #undef JUMP_
  4182. // -----------------------------------------------------------------------------
  4183. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4184. const typename sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::size_type
  4185. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::ILLEGAL_BUCKET;
  4186. // How full we let the table get before we resize. Knuth says .8 is
  4187. // good -- higher causes us to probe too much, though saves memory
  4188. // -----------------------------------------------------------------------------
  4189. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4190. const int sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_PCT = 50;
  4191. // How empty we let the table get before we resize lower.
  4192. // It should be less than OCCUPANCY_PCT / 2 or we thrash resizing
  4193. // -----------------------------------------------------------------------------
  4194. template <class V, class K, class HF, class ExK, class SetK, class EqK, class A>
  4195. const int sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_EMPTY_PCT
  4196. = static_cast<int>(0.4 *
  4197. sparse_hashtable<V,K,HF,ExK,SetK,EqK,A>::HT_OCCUPANCY_PCT);
  4198. // ----------------------------------------------------------------------
  4199. // S P A R S E _ H A S H _ M A P
  4200. // ----------------------------------------------------------------------
  4201. template <class Key, class T,
  4202. class HashFcn = spp_hash<Key>,
  4203. class EqualKey = std::equal_to<Key>,
  4204. class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
  4205. class sparse_hash_map
  4206. {
  4207. private:
  4208. // Apparently select1st is not stl-standard, so we define our own
  4209. struct SelectKey
  4210. {
  4211. typedef const Key& result_type;
  4212. inline const Key& operator()(const std::pair<const Key, T>& p) const
  4213. {
  4214. return p.first;
  4215. }
  4216. };
  4217. struct SetKey
  4218. {
  4219. inline void operator()(std::pair<const Key, T>* value, const Key& new_key) const
  4220. {
  4221. *const_cast<Key*>(&value->first) = new_key;
  4222. }
  4223. };
  4224. // For operator[].
  4225. struct DefaultValue
  4226. {
  4227. inline std::pair<const Key, T> operator()(const Key& key) const
  4228. {
  4229. return std::make_pair(key, T());
  4230. }
  4231. };
  4232. // The actual data
  4233. typedef sparse_hashtable<std::pair<typename spp_::remove_const<Key>::type, T>, Key, HashFcn, SelectKey,
  4234. SetKey, EqualKey, Alloc> ht;
  4235. public:
  4236. typedef typename ht::key_type key_type;
  4237. typedef T data_type;
  4238. typedef T mapped_type;
  4239. typedef typename std::pair<const Key, T> value_type;
  4240. typedef typename ht::hasher hasher;
  4241. typedef typename ht::key_equal key_equal;
  4242. typedef Alloc allocator_type;
  4243. typedef typename ht::size_type size_type;
  4244. typedef typename ht::difference_type difference_type;
  4245. typedef typename ht::pointer pointer;
  4246. typedef typename ht::const_pointer const_pointer;
  4247. typedef typename ht::reference reference;
  4248. typedef typename ht::const_reference const_reference;
  4249. typedef typename ht::iterator iterator;
  4250. typedef typename ht::const_iterator const_iterator;
  4251. typedef typename ht::local_iterator local_iterator;
  4252. typedef typename ht::const_local_iterator const_local_iterator;
  4253. // Iterator functions
  4254. iterator begin() { return rep.begin(); }
  4255. iterator end() { return rep.end(); }
  4256. const_iterator begin() const { return rep.cbegin(); }
  4257. const_iterator end() const { return rep.cend(); }
  4258. const_iterator cbegin() const { return rep.cbegin(); }
  4259. const_iterator cend() const { return rep.cend(); }
  4260. // These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
  4261. local_iterator begin(size_type i) { return rep.begin(i); }
  4262. local_iterator end(size_type i) { return rep.end(i); }
  4263. const_local_iterator begin(size_type i) const { return rep.begin(i); }
  4264. const_local_iterator end(size_type i) const { return rep.end(i); }
  4265. const_local_iterator cbegin(size_type i) const { return rep.cbegin(i); }
  4266. const_local_iterator cend(size_type i) const { return rep.cend(i); }
  4267. // Accessor functions
  4268. // ------------------
  4269. allocator_type get_allocator() const { return rep.get_allocator(); }
  4270. hasher hash_funct() const { return rep.hash_funct(); }
  4271. hasher hash_function() const { return hash_funct(); }
  4272. key_equal key_eq() const { return rep.key_eq(); }
  4273. // Constructors
  4274. // ------------
  4275. explicit sparse_hash_map(size_type n = 0,
  4276. const hasher& hf = hasher(),
  4277. const key_equal& eql = key_equal(),
  4278. const allocator_type& alloc = allocator_type())
  4279. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4280. {
  4281. }
  4282. explicit sparse_hash_map(const allocator_type& alloc) :
  4283. rep(0, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4284. {
  4285. }
  4286. sparse_hash_map(size_type n, const allocator_type& alloc) :
  4287. rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4288. {
  4289. }
  4290. sparse_hash_map(size_type n, const hasher& hf, const allocator_type& alloc) :
  4291. rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4292. {
  4293. }
  4294. template <class InputIterator>
  4295. sparse_hash_map(InputIterator f, InputIterator l,
  4296. size_type n = 0,
  4297. const hasher& hf = hasher(),
  4298. const key_equal& eql = key_equal(),
  4299. const allocator_type& alloc = allocator_type())
  4300. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4301. {
  4302. rep.insert(f, l);
  4303. }
  4304. template <class InputIterator>
  4305. sparse_hash_map(InputIterator f, InputIterator l,
  4306. size_type n, const allocator_type& alloc)
  4307. : rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4308. {
  4309. rep.insert(f, l);
  4310. }
  4311. template <class InputIterator>
  4312. sparse_hash_map(InputIterator f, InputIterator l,
  4313. size_type n, const hasher& hf, const allocator_type& alloc)
  4314. : rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4315. {
  4316. rep.insert(f, l);
  4317. }
  4318. sparse_hash_map(const sparse_hash_map &o) :
  4319. rep(o.rep)
  4320. {}
  4321. sparse_hash_map(const sparse_hash_map &o,
  4322. const allocator_type& alloc) :
  4323. rep(o.rep, alloc)
  4324. {}
  4325. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  4326. sparse_hash_map(const sparse_hash_map &&o) :
  4327. rep(std::move(o.rep))
  4328. {}
  4329. sparse_hash_map(const sparse_hash_map &&o,
  4330. const allocator_type& alloc) :
  4331. rep(std::move(o.rep), alloc)
  4332. {}
  4333. #endif
  4334. #if !defined(SPP_NO_CXX11_HDR_INITIALIZER_LIST)
  4335. sparse_hash_map(std::initializer_list<value_type> init,
  4336. size_type n = 0,
  4337. const hasher& hf = hasher(),
  4338. const key_equal& eql = key_equal(),
  4339. const allocator_type& alloc = allocator_type())
  4340. : rep(n, hf, eql, SelectKey(), SetKey(), alloc)
  4341. {
  4342. rep.insert(init.begin(), init.end());
  4343. }
  4344. sparse_hash_map(std::initializer_list<value_type> init,
  4345. size_type n, const allocator_type& alloc) :
  4346. rep(n, hasher(), key_equal(), SelectKey(), SetKey(), alloc)
  4347. {
  4348. rep.insert(init.begin(), init.end());
  4349. }
  4350. sparse_hash_map(std::initializer_list<value_type> init,
  4351. size_type n, const hasher& hf, const allocator_type& alloc) :
  4352. rep(n, hf, key_equal(), SelectKey(), SetKey(), alloc)
  4353. {
  4354. rep.insert(init.begin(), init.end());
  4355. }
  4356. sparse_hash_map& operator=(std::initializer_list<value_type> init)
  4357. {
  4358. rep.clear();
  4359. rep.insert(init.begin(), init.end());
  4360. return *this;
  4361. }
  4362. void insert(std::initializer_list<value_type> init)
  4363. {
  4364. rep.insert(init.begin(), init.end());
  4365. }
  4366. #endif
  4367. sparse_hash_map& operator=(const sparse_hash_map &o)
  4368. {
  4369. rep = o.rep;
  4370. return *this;
  4371. }
  4372. void clear() { rep.clear(); }
  4373. void swap(sparse_hash_map& hs) { rep.swap(hs.rep); }
  4374. // Functions concerning size
  4375. // -------------------------
  4376. size_type size() const { return rep.size(); }
  4377. size_type max_size() const { return rep.max_size(); }
  4378. bool empty() const { return rep.empty(); }
  4379. size_type bucket_count() const { return rep.bucket_count(); }
  4380. size_type max_bucket_count() const { return rep.max_bucket_count(); }
  4381. size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
  4382. size_type bucket(const key_type& key) const { return rep.bucket(key); }
  4383. float load_factor() const { return size() * 1.0f / bucket_count(); }
  4384. float max_load_factor() const { return rep.get_enlarge_factor(); }
  4385. void max_load_factor(float grow) { rep.set_enlarge_factor(grow); }
  4386. float min_load_factor() const { return rep.get_shrink_factor(); }
  4387. void min_load_factor(float shrink){ rep.set_shrink_factor(shrink); }
  4388. void set_resizing_parameters(float shrink, float grow)
  4389. {
  4390. rep.set_resizing_parameters(shrink, grow);
  4391. }
  4392. void resize(size_type cnt) { rep.resize(cnt); }
  4393. void rehash(size_type cnt) { resize(cnt); } // c++11 name
  4394. void reserve(size_type cnt) { resize(cnt); } // c++11
  4395. // Lookup
  4396. // ------
  4397. iterator find(const key_type& key) { return rep.find(key); }
  4398. const_iterator find(const key_type& key) const { return rep.find(key); }
  4399. mapped_type& operator[](const key_type& key)
  4400. {
  4401. return rep.template find_or_insert<DefaultValue>(key).second;
  4402. }
  4403. size_type count(const key_type& key) const { return rep.count(key); }
  4404. std::pair<iterator, iterator>
  4405. equal_range(const key_type& key) { return rep.equal_range(key); }
  4406. std::pair<const_iterator, const_iterator>
  4407. equal_range(const key_type& key) const { return rep.equal_range(key); }
  4408. mapped_type& at(const key_type& key)
  4409. {
  4410. iterator it = rep.find(key);
  4411. if (it == rep.end())
  4412. throw_exception(std::out_of_range("at: key not present"));
  4413. return it->second;
  4414. }
  4415. const mapped_type& at(const key_type& key) const
  4416. {
  4417. const_iterator it = rep.find(key);
  4418. if (it == rep.cend())
  4419. throw_exception(std::out_of_range("at: key not present"));
  4420. return it->second;
  4421. }
  4422. // Insert
  4423. // ------
  4424. std::pair<iterator, bool>
  4425. insert(const value_type& obj) { return rep.insert(obj); }
  4426. template <class InputIterator>
  4427. void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
  4428. void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
  4429. iterator insert(iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4430. iterator insert(const_iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4431. // Deleted key routines - just to keep google test framework happy
  4432. // we don't actually use the deleted key
  4433. // ---------------------------------------------------------------
  4434. void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
  4435. void clear_deleted_key() { rep.clear_deleted_key(); }
  4436. key_type deleted_key() const { return rep.deleted_key(); }
  4437. // Erase
  4438. // -----
  4439. size_type erase(const key_type& key) { return rep.erase(key); }
  4440. iterator erase(iterator it) { return rep.erase(it); }
  4441. iterator erase(iterator f, iterator l) { return rep.erase(f, l); }
  4442. iterator erase(const_iterator it) { return rep.erase(it); }
  4443. iterator erase(const_iterator f, const_iterator l){ return rep.erase(f, l); }
  4444. // Comparison
  4445. // ----------
  4446. bool operator==(const sparse_hash_map& hs) const { return rep == hs.rep; }
  4447. bool operator!=(const sparse_hash_map& hs) const { return rep != hs.rep; }
  4448. // I/O -- this is an add-on for writing metainformation to disk
  4449. //
  4450. // For maximum flexibility, this does not assume a particular
  4451. // file type (though it will probably be a FILE *). We just pass
  4452. // the fp through to rep.
  4453. // If your keys and values are simple enough, you can pass this
  4454. // serializer to serialize()/unserialize(). "Simple enough" means
  4455. // value_type is a POD type that contains no pointers. Note,
  4456. // however, we don't try to normalize endianness.
  4457. // ---------------------------------------------------------------
  4458. typedef typename ht::NopointerSerializer NopointerSerializer;
  4459. // serializer: a class providing operator()(OUTPUT*, const value_type&)
  4460. // (writing value_type to OUTPUT). You can specify a
  4461. // NopointerSerializer object if appropriate (see above).
  4462. // fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
  4463. // pointer to a class providing size_t Write(const void*, size_t),
  4464. // which writes a buffer into a stream (which fp presumably
  4465. // owns) and returns the number of bytes successfully written.
  4466. // Note basic_ostream<not_char> is not currently supported.
  4467. // ---------------------------------------------------------------
  4468. template <typename ValueSerializer, typename OUTPUT>
  4469. bool serialize(ValueSerializer serializer, OUTPUT* fp)
  4470. {
  4471. return rep.serialize(serializer, fp);
  4472. }
  4473. // serializer: a functor providing operator()(INPUT*, value_type*)
  4474. // (reading from INPUT and into value_type). You can specify a
  4475. // NopointerSerializer object if appropriate (see above).
  4476. // fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
  4477. // pointer to a class providing size_t Read(void*, size_t),
  4478. // which reads into a buffer from a stream (which fp presumably
  4479. // owns) and returns the number of bytes successfully read.
  4480. // Note basic_istream<not_char> is not currently supported.
  4481. // NOTE: Since value_type is std::pair<const Key, T>, ValueSerializer
  4482. // may need to do a const cast in order to fill in the key.
  4483. // NOTE: if Key or T are not POD types, the serializer MUST use
  4484. // placement-new to initialize their values, rather than a normal
  4485. // equals-assignment or similar. (The value_type* passed into the
  4486. // serializer points to garbage memory.)
  4487. // ---------------------------------------------------------------
  4488. template <typename ValueSerializer, typename INPUT>
  4489. bool unserialize(ValueSerializer serializer, INPUT* fp)
  4490. {
  4491. return rep.unserialize(serializer, fp);
  4492. }
  4493. // The four methods below are DEPRECATED.
  4494. // Use serialize() and unserialize() for new code.
  4495. // -----------------------------------------------
  4496. template <typename OUTPUT>
  4497. bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
  4498. template <typename INPUT>
  4499. bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
  4500. template <typename OUTPUT>
  4501. bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
  4502. template <typename INPUT>
  4503. bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
  4504. private:
  4505. // The actual data
  4506. // ---------------
  4507. ht rep;
  4508. };
  4509. // We need a global swap as well
  4510. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  4511. inline void swap(sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
  4512. sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
  4513. {
  4514. hm1.swap(hm2);
  4515. }
  4516. // ----------------------------------------------------------------------
  4517. // S P A R S E _ H A S H _ S E T
  4518. // ----------------------------------------------------------------------
  4519. template <class Value,
  4520. class HashFcn = spp_hash<Value>,
  4521. class EqualKey = std::equal_to<Value>,
  4522. class Alloc = libc_allocator_with_realloc<Value> >
  4523. class sparse_hash_set
  4524. {
  4525. private:
  4526. // Apparently identity is not stl-standard, so we define our own
  4527. struct Identity
  4528. {
  4529. typedef const Value& result_type;
  4530. const Value& operator()(const Value& v) const { return v; }
  4531. };
  4532. struct SetKey
  4533. {
  4534. void operator()(Value* value, const Value& new_key) const
  4535. {
  4536. *value = new_key;
  4537. }
  4538. };
  4539. typedef sparse_hashtable<Value, Value, HashFcn, Identity, SetKey,
  4540. EqualKey, Alloc> ht;
  4541. public:
  4542. typedef typename ht::key_type key_type;
  4543. typedef typename ht::value_type value_type;
  4544. typedef typename ht::hasher hasher;
  4545. typedef typename ht::key_equal key_equal;
  4546. typedef Alloc allocator_type;
  4547. typedef typename ht::size_type size_type;
  4548. typedef typename ht::difference_type difference_type;
  4549. typedef typename ht::const_pointer pointer;
  4550. typedef typename ht::const_pointer const_pointer;
  4551. typedef typename ht::const_reference reference;
  4552. typedef typename ht::const_reference const_reference;
  4553. typedef typename ht::const_iterator iterator;
  4554. typedef typename ht::const_iterator const_iterator;
  4555. typedef typename ht::const_local_iterator local_iterator;
  4556. typedef typename ht::const_local_iterator const_local_iterator;
  4557. // Iterator functions -- recall all iterators are const
  4558. iterator begin() const { return rep.begin(); }
  4559. iterator end() const { return rep.end(); }
  4560. const_iterator cbegin() const { return rep.cbegin(); }
  4561. const_iterator cend() const { return rep.cend(); }
  4562. // These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
  4563. local_iterator begin(size_type i) const { return rep.begin(i); }
  4564. local_iterator end(size_type i) const { return rep.end(i); }
  4565. local_iterator cbegin(size_type i) const { return rep.cbegin(i); }
  4566. local_iterator cend(size_type i) const { return rep.cend(i); }
  4567. // Accessor functions
  4568. // ------------------
  4569. allocator_type get_allocator() const { return rep.get_allocator(); }
  4570. hasher hash_funct() const { return rep.hash_funct(); }
  4571. hasher hash_function() const { return hash_funct(); } // tr1 name
  4572. key_equal key_eq() const { return rep.key_eq(); }
  4573. // Constructors
  4574. // ------------
  4575. explicit sparse_hash_set(size_type n = 0,
  4576. const hasher& hf = hasher(),
  4577. const key_equal& eql = key_equal(),
  4578. const allocator_type& alloc = allocator_type()) :
  4579. rep(n, hf, eql, Identity(), SetKey(), alloc)
  4580. {
  4581. }
  4582. explicit sparse_hash_set(const allocator_type& alloc) :
  4583. rep(0, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4584. {
  4585. }
  4586. sparse_hash_set(size_type n, const allocator_type& alloc) :
  4587. rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4588. {
  4589. }
  4590. sparse_hash_set(size_type n, const hasher& hf,
  4591. const allocator_type& alloc) :
  4592. rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4593. {
  4594. }
  4595. template <class InputIterator>
  4596. sparse_hash_set(InputIterator f, InputIterator l,
  4597. size_type n = 0,
  4598. const hasher& hf = hasher(),
  4599. const key_equal& eql = key_equal(),
  4600. const allocator_type& alloc = allocator_type())
  4601. : rep(n, hf, eql, Identity(), SetKey(), alloc)
  4602. {
  4603. rep.insert(f, l);
  4604. }
  4605. template <class InputIterator>
  4606. sparse_hash_set(InputIterator f, InputIterator l,
  4607. size_type n, const allocator_type& alloc)
  4608. : rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4609. {
  4610. rep.insert(f, l);
  4611. }
  4612. template <class InputIterator>
  4613. sparse_hash_set(InputIterator f, InputIterator l,
  4614. size_type n, const hasher& hf, const allocator_type& alloc)
  4615. : rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4616. {
  4617. rep.insert(f, l);
  4618. }
  4619. sparse_hash_set(const sparse_hash_set &o) :
  4620. rep(o.rep)
  4621. {}
  4622. sparse_hash_set(const sparse_hash_set &o,
  4623. const allocator_type& alloc) :
  4624. rep(o.rep, alloc)
  4625. {}
  4626. #if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)
  4627. sparse_hash_set(const sparse_hash_set &&o) :
  4628. rep(std::move(o.rep))
  4629. {}
  4630. sparse_hash_set(const sparse_hash_set &&o,
  4631. const allocator_type& alloc) :
  4632. rep(std::move(o.rep), alloc)
  4633. {}
  4634. #endif
  4635. #if !defined(SPP_NO_CXX11_HDR_INITIALIZER_LIST)
  4636. sparse_hash_set(std::initializer_list<value_type> init,
  4637. size_type n = 0,
  4638. const hasher& hf = hasher(),
  4639. const key_equal& eql = key_equal(),
  4640. const allocator_type& alloc = allocator_type()) :
  4641. rep(n, hf, eql, Identity(), SetKey(), alloc)
  4642. {
  4643. rep.insert(init.begin(), init.end());
  4644. }
  4645. sparse_hash_set(std::initializer_list<value_type> init,
  4646. size_type n, const allocator_type& alloc) :
  4647. rep(n, hasher(), key_equal(), Identity(), SetKey(), alloc)
  4648. {
  4649. rep.insert(init.begin(), init.end());
  4650. }
  4651. sparse_hash_set(std::initializer_list<value_type> init,
  4652. size_type n, const hasher& hf,
  4653. const allocator_type& alloc) :
  4654. rep(n, hf, key_equal(), Identity(), SetKey(), alloc)
  4655. {
  4656. rep.insert(init.begin(), init.end());
  4657. }
  4658. sparse_hash_set& operator=(std::initializer_list<value_type> init)
  4659. {
  4660. rep.clear();
  4661. rep.insert(init.begin(), init.end());
  4662. return *this;
  4663. }
  4664. void insert(std::initializer_list<value_type> init)
  4665. {
  4666. rep.insert(init.begin(), init.end());
  4667. }
  4668. #endif
  4669. sparse_hash_set& operator=(const sparse_hash_set &o)
  4670. {
  4671. rep = o.rep;
  4672. return *this;
  4673. }
  4674. void clear() { rep.clear(); }
  4675. void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
  4676. // Functions concerning size
  4677. // -------------------------
  4678. size_type size() const { return rep.size(); }
  4679. size_type max_size() const { return rep.max_size(); }
  4680. bool empty() const { return rep.empty(); }
  4681. size_type bucket_count() const { return rep.bucket_count(); }
  4682. size_type max_bucket_count() const { return rep.max_bucket_count(); }
  4683. size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
  4684. size_type bucket(const key_type& key) const { return rep.bucket(key); }
  4685. float load_factor() const { return size() * 1.0f / bucket_count(); }
  4686. float max_load_factor() const { return rep.get_enlarge_factor(); }
  4687. void max_load_factor(float grow) { rep.set_enlarge_factor(grow); }
  4688. float min_load_factor() const { return rep.get_shrink_factor(); }
  4689. void min_load_factor(float shrink){ rep.set_shrink_factor(shrink); }
  4690. void set_resizing_parameters(float shrink, float grow)
  4691. {
  4692. rep.set_resizing_parameters(shrink, grow);
  4693. }
  4694. void resize(size_type cnt) { rep.resize(cnt); }
  4695. void rehash(size_type cnt) { resize(cnt); } // c++11 name
  4696. void reserve(size_type cnt) { resize(cnt); } // c++11
  4697. // Lookup
  4698. // ------
  4699. iterator find(const key_type& key) const { return rep.find(key); }
  4700. size_type count(const key_type& key) const { return rep.count(key); }
  4701. std::pair<iterator, iterator>
  4702. equal_range(const key_type& key) const { return rep.equal_range(key); }
  4703. #if 0 && !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)
  4704. template <class... Args>
  4705. pair<iterator, bool> emplace(Args&&... args)
  4706. {
  4707. return rep.emplace_unique(std::forward<Args>(args)...);
  4708. }
  4709. template <class... Args>
  4710. iterator emplace_hint(const_iterator p, Args&&... args)
  4711. {
  4712. return rep.emplace_unique(std::forward<Args>(args)...).first;
  4713. }
  4714. #endif
  4715. // Insert
  4716. // ------
  4717. std::pair<iterator, bool> insert(const value_type& obj)
  4718. {
  4719. std::pair<typename ht::iterator, bool> p = rep.insert(obj);
  4720. return std::pair<iterator, bool>(p.first, p.second); // const to non-const
  4721. }
  4722. template <class InputIterator>
  4723. void insert(InputIterator f, InputIterator l) { rep.insert(f, l); }
  4724. void insert(const_iterator f, const_iterator l) { rep.insert(f, l); }
  4725. iterator insert(iterator /*unused*/, const value_type& obj) { return insert(obj).first; }
  4726. // Deleted key - do nothing - just to keep google test framework happy
  4727. // -------------------------------------------------------------------
  4728. void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
  4729. void clear_deleted_key() { rep.clear_deleted_key(); }
  4730. key_type deleted_key() const { return rep.deleted_key(); }
  4731. // Erase
  4732. // -----
  4733. size_type erase(const key_type& key) { return rep.erase(key); }
  4734. iterator erase(iterator it) { return rep.erase(it); }
  4735. iterator erase(iterator f, iterator l) { return rep.erase(f, l); }
  4736. // Comparison
  4737. // ----------
  4738. bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
  4739. bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
  4740. // I/O -- this is an add-on for writing metainformation to disk
  4741. //
  4742. // For maximum flexibility, this does not assume a particular
  4743. // file type (though it will probably be a FILE *). We just pass
  4744. // the fp through to rep.
  4745. // If your keys and values are simple enough, you can pass this
  4746. // serializer to serialize()/unserialize(). "Simple enough" means
  4747. // value_type is a POD type that contains no pointers. Note,
  4748. // however, we don't try to normalize endianness.
  4749. // ---------------------------------------------------------------
  4750. typedef typename ht::NopointerSerializer NopointerSerializer;
  4751. // serializer: a class providing operator()(OUTPUT*, const value_type&)
  4752. // (writing value_type to OUTPUT). You can specify a
  4753. // NopointerSerializer object if appropriate (see above).
  4754. // fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
  4755. // pointer to a class providing size_t Write(const void*, size_t),
  4756. // which writes a buffer into a stream (which fp presumably
  4757. // owns) and returns the number of bytes successfully written.
  4758. // Note basic_ostream<not_char> is not currently supported.
  4759. // ---------------------------------------------------------------
  4760. template <typename ValueSerializer, typename OUTPUT>
  4761. bool serialize(ValueSerializer serializer, OUTPUT* fp)
  4762. {
  4763. return rep.serialize(serializer, fp);
  4764. }
  4765. // serializer: a functor providing operator()(INPUT*, value_type*)
  4766. // (reading from INPUT and into value_type). You can specify a
  4767. // NopointerSerializer object if appropriate (see above).
  4768. // fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
  4769. // pointer to a class providing size_t Read(void*, size_t),
  4770. // which reads into a buffer from a stream (which fp presumably
  4771. // owns) and returns the number of bytes successfully read.
  4772. // Note basic_istream<not_char> is not currently supported.
  4773. // NOTE: Since value_type is const Key, ValueSerializer
  4774. // may need to do a const cast in order to fill in the key.
  4775. // NOTE: if Key is not a POD type, the serializer MUST use
  4776. // placement-new to initialize its value, rather than a normal
  4777. // equals-assignment or similar. (The value_type* passed into
  4778. // the serializer points to garbage memory.)
  4779. // ---------------------------------------------------------------
  4780. template <typename ValueSerializer, typename INPUT>
  4781. bool unserialize(ValueSerializer serializer, INPUT* fp)
  4782. {
  4783. return rep.unserialize(serializer, fp);
  4784. }
  4785. // The four methods below are DEPRECATED.
  4786. // Use serialize() and unserialize() for new code.
  4787. // -----------------------------------------------
  4788. template <typename OUTPUT>
  4789. bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
  4790. template <typename INPUT>
  4791. bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
  4792. template <typename OUTPUT>
  4793. bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
  4794. template <typename INPUT>
  4795. bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
  4796. private:
  4797. // The actual data
  4798. // ---------------
  4799. ht rep;
  4800. };
  4801. template <class Val, class HashFcn, class EqualKey, class Alloc>
  4802. inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
  4803. sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2)
  4804. {
  4805. hs1.swap(hs2);
  4806. }
  4807. SPP_END_NAMESPACE
  4808. #endif // sparsepp_h_guard_