mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 23:36:00 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
131
BeefySysLib/third_party/sparsehash/config.h.in
vendored
Normal file
131
BeefySysLib/third_party/sparsehash/config.h.in
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
/* src/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Namespace for Google classes */
|
||||
#undef GOOGLE_NAMESPACE
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#undef HASH_FUN_H
|
||||
|
||||
/* the location of <unordered_map> or <hash_map> */
|
||||
#undef HASH_MAP_H
|
||||
|
||||
/* the namespace of the hash<> function */
|
||||
#undef HASH_NAMESPACE
|
||||
|
||||
/* the location of <unordered_set> or <hash_set> */
|
||||
#undef HASH_SET_H
|
||||
|
||||
/* Define to 1 if you have the <google/malloc_extension.h> header file. */
|
||||
#undef HAVE_GOOGLE_MALLOC_EXTENSION_H
|
||||
|
||||
/* define if the compiler has hash_map */
|
||||
#undef HAVE_HASH_MAP
|
||||
|
||||
/* define if the compiler has hash_set */
|
||||
#undef HAVE_HASH_SET
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#undef HAVE_LONG_LONG
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#undef HAVE_MEMCPY
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#undef HAVE_MEMMOVE
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* define if the compiler implements namespaces */
|
||||
#undef HAVE_NAMESPACES
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#undef HAVE_SYS_UTSNAME_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* define if the compiler supports unordered_{map,set} */
|
||||
#undef HAVE_UNORDERED_MAP
|
||||
|
||||
/* Define to 1 if the system has the type `u_int16_t'. */
|
||||
#undef HAVE_U_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `__uint16'. */
|
||||
#undef HAVE___UINT16
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
|
||||
/* The system-provided hash function including the namespace. */
|
||||
#undef SPARSEHASH_HASH
|
||||
|
||||
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
|
||||
#undef SPARSEHASH_HASH_NO_NAMESPACE
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Stops putting the code inside the Google namespace */
|
||||
#undef _END_GOOGLE_NAMESPACE_
|
||||
|
||||
/* Puts following code inside the Google namespace */
|
||||
#undef _START_GOOGLE_NAMESPACE_
|
22
BeefySysLib/third_party/sparsehash/config.h.include
vendored
Normal file
22
BeefySysLib/third_party/sparsehash/config.h.include
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/***
|
||||
*** These are #defines that autoheader puts in config.h.in that we
|
||||
*** want to show up in sparseconfig.h, the minimal config.h file
|
||||
*** #included by all our .h files. The reason we don't take
|
||||
*** everything that autoheader emits is that we have to include a
|
||||
*** config.h in installed header files, and we want to minimize the
|
||||
*** number of #defines we make so as to not pollute the namespace.
|
||||
***/
|
||||
GOOGLE_NAMESPACE
|
||||
HASH_NAMESPACE
|
||||
HASH_FUN_H
|
||||
SPARSEHASH_HASH
|
||||
HAVE_UINT16_T
|
||||
HAVE_U_INT16_T
|
||||
HAVE___UINT16
|
||||
HAVE_LONG_LONG
|
||||
HAVE_SYS_TYPES_H
|
||||
HAVE_STDINT_H
|
||||
HAVE_INTTYPES_H
|
||||
HAVE_MEMCPY
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
_START_GOOGLE_NAMESPACE_
|
34
BeefySysLib/third_party/sparsehash/google/dense_hash_map
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/dense_hash_map
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/dense_hash_map>
|
34
BeefySysLib/third_party/sparsehash/google/dense_hash_set
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/dense_hash_set
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/dense_hash_set>
|
34
BeefySysLib/third_party/sparsehash/google/sparse_hash_map
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparse_hash_map
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/sparse_hash_map>
|
34
BeefySysLib/third_party/sparsehash/google/sparse_hash_set
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparse_hash_set
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/sparse_hash_set>
|
35
BeefySysLib/third_party/sparsehash/google/sparsehash/densehashtable.h
vendored
Normal file
35
BeefySysLib/third_party/sparsehash/google/sparsehash/densehashtable.h
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/internal/densehashtable.h>
|
||||
|
34
BeefySysLib/third_party/sparsehash/google/sparsehash/hashtable-common.h
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparsehash/hashtable-common.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/internal/hashtable-common.h>
|
34
BeefySysLib/third_party/sparsehash/google/sparsehash/libc_allocator_with_realloc.h
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparsehash/libc_allocator_with_realloc.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
34
BeefySysLib/third_party/sparsehash/google/sparsehash/sparsehashtable.h
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparsehash/sparsehashtable.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/internal/sparsehashtable.h>
|
34
BeefySysLib/third_party/sparsehash/google/sparsetable
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/sparsetable
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/sparsetable>
|
34
BeefySysLib/third_party/sparsehash/google/template_util.h
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/template_util.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/template_util.h>
|
34
BeefySysLib/third_party/sparsehash/google/type_traits.h
vendored
Normal file
34
BeefySysLib/third_party/sparsehash/google/type_traits.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2012, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Header files have moved from the google directory to the sparsehash
|
||||
// directory. This forwarding file is provided only for backwards
|
||||
// compatibility. Use <sparsehash/*> in all new code.
|
||||
|
||||
#include <sparsehash/type_traits.h>
|
1038
BeefySysLib/third_party/sparsehash/hash_test_interface.h
vendored
Normal file
1038
BeefySysLib/third_party/sparsehash/hash_test_interface.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
2037
BeefySysLib/third_party/sparsehash/hashtable_test.cc
vendored
Normal file
2037
BeefySysLib/third_party/sparsehash/hashtable_test.cc
vendored
Normal file
File diff suppressed because it is too large
Load diff
122
BeefySysLib/third_party/sparsehash/libc_allocator_with_realloc_test.cc
vendored
Normal file
122
BeefySysLib/third_party/sparsehash/libc_allocator_with_realloc_test.cc
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
// Copyright (c) 2010, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include "testutil.h"
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::string;
|
||||
using std::basic_string;
|
||||
using std::char_traits;
|
||||
using std::vector;
|
||||
using GOOGLE_NAMESPACE::libc_allocator_with_realloc;
|
||||
|
||||
#define arraysize(a) ( sizeof(a) / sizeof(*(a)) )
|
||||
|
||||
namespace {
|
||||
|
||||
typedef libc_allocator_with_realloc<int> int_alloc;
|
||||
typedef int_alloc::rebind<int*>::other intp_alloc;
|
||||
|
||||
// cstring allocates from libc_allocator_with_realloc.
|
||||
typedef basic_string<char, char_traits<char>,
|
||||
libc_allocator_with_realloc<char> > cstring;
|
||||
typedef vector<cstring, libc_allocator_with_realloc<cstring> > cstring_vector;
|
||||
|
||||
TEST(LibcAllocatorWithReallocTest, Allocate) {
|
||||
int_alloc alloc;
|
||||
intp_alloc palloc;
|
||||
|
||||
int** parray = palloc.allocate(1024);
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
parray[i] = alloc.allocate(i * 1024 + 1);
|
||||
}
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
alloc.deallocate(parray[i], i * 1024 + 1);
|
||||
}
|
||||
palloc.deallocate(parray, 1024);
|
||||
|
||||
int* p = alloc.allocate(4096);
|
||||
p[0] = 1;
|
||||
p[1023] = 2;
|
||||
p[4095] = 3;
|
||||
p = alloc.reallocate(p, 8192);
|
||||
EXPECT_EQ(1, p[0]);
|
||||
EXPECT_EQ(2, p[1023]);
|
||||
EXPECT_EQ(3, p[4095]);
|
||||
p = alloc.reallocate(p, 1024);
|
||||
EXPECT_EQ(1, p[0]);
|
||||
EXPECT_EQ(2, p[1023]);
|
||||
alloc.deallocate(p, 1024);
|
||||
}
|
||||
|
||||
TEST(LibcAllocatorWithReallocTest, TestSTL) {
|
||||
// Test strings copied from base/arena_unittest.cc
|
||||
static const char* test_strings[] = {
|
||||
"aback", "abaft", "abandon", "abandoned", "abandoning",
|
||||
"abandonment", "abandons", "abase", "abased", "abasement",
|
||||
"abasements", "abases", "abash", "abashed", "abashes", "abashing",
|
||||
"abasing", "abate", "abated", "abatement", "abatements", "abater",
|
||||
"abates", "abating", "abbe", "abbey", "abbeys", "abbot", "abbots",
|
||||
"abbreviate", "abbreviated", "abbreviates", "abbreviating",
|
||||
"abbreviation", "abbreviations", "abdomen", "abdomens", "abdominal",
|
||||
"abduct", "abducted", "abduction", "abductions", "abductor", "abductors",
|
||||
"abducts", "Abe", "abed", "Abel", "Abelian", "Abelson", "Aberdeen",
|
||||
"Abernathy", "aberrant", "aberration", "aberrations", "abet", "abets",
|
||||
"abetted", "abetter", "abetting", "abeyance", "abhor", "abhorred",
|
||||
"abhorrent", "abhorrer", "abhorring", "abhors", "abide", "abided",
|
||||
"abides", "abiding"};
|
||||
cstring_vector v;
|
||||
for (size_t i = 0; i < arraysize(test_strings); ++i) {
|
||||
v.push_back(test_strings[i]);
|
||||
}
|
||||
for (size_t i = arraysize(test_strings); i > 0; --i) {
|
||||
EXPECT_EQ(cstring(test_strings[i-1]), v.back());
|
||||
v.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int, char **) {
|
||||
// All the work is done in the static constructors. If they don't
|
||||
// die, the tests have all passed.
|
||||
cout << "PASS\n";
|
||||
return 0;
|
||||
}
|
||||
|
106
BeefySysLib/third_party/sparsehash/simple_compat_test.cc
vendored
Normal file
106
BeefySysLib/third_party/sparsehash/simple_compat_test.cc
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// This tests mostly that we can #include the files correctly
|
||||
// and have them work. It is like simple_test.cc but uses the
|
||||
// compatibility #include directory (google/) rather than the
|
||||
// canonical one (sparsehash/). This unittest purposefully does
|
||||
// not #include <config.h>; it's meant to emulate what a 'regular
|
||||
// install' of sparsehash would be able to see.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <google/sparse_hash_set>
|
||||
#include <google/sparse_hash_map>
|
||||
#include <google/dense_hash_set>
|
||||
#include <google/dense_hash_map>
|
||||
#include <google/template_util.h>
|
||||
#include <google/type_traits.h>
|
||||
|
||||
#define CHECK_IFF(cond, when) do { \
|
||||
if (when) { \
|
||||
if (!(cond)) { \
|
||||
puts("ERROR: " #cond " failed when " #when " is true\n"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} else { \
|
||||
if (cond) { \
|
||||
puts("ERROR: " #cond " succeeded when " #when " is false\n"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main(int argc, char**) {
|
||||
// Run with an argument to get verbose output
|
||||
const bool verbose = argc > 1;
|
||||
|
||||
google::sparse_hash_set<int> sset;
|
||||
google::sparse_hash_map<int, int> smap;
|
||||
google::dense_hash_set<int> dset;
|
||||
google::dense_hash_map<int, int> dmap;
|
||||
dset.set_empty_key(-1);
|
||||
dmap.set_empty_key(-1);
|
||||
|
||||
for (int i = 0; i < 100; i += 10) { // go by tens
|
||||
sset.insert(i);
|
||||
smap[i] = i+1;
|
||||
dset.insert(i + 5);
|
||||
dmap[i+5] = i+6;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
for (google::sparse_hash_set<int>::const_iterator it = sset.begin();
|
||||
it != sset.end(); ++it)
|
||||
printf("sset: %d\n", *it);
|
||||
for (google::sparse_hash_map<int,int>::const_iterator it = smap.begin();
|
||||
it != smap.end(); ++it)
|
||||
printf("smap: %d -> %d\n", it->first, it->second);
|
||||
for (google::dense_hash_set<int>::const_iterator it = dset.begin();
|
||||
it != dset.end(); ++it)
|
||||
printf("dset: %d\n", *it);
|
||||
for (google::dense_hash_map<int,int>::const_iterator it = dmap.begin();
|
||||
it != dmap.end(); ++it)
|
||||
printf("dmap: %d -> %d\n", it->first, it->second);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
CHECK_IFF(sset.find(i) != sset.end(), (i % 10) == 0);
|
||||
CHECK_IFF(smap.find(i) != smap.end(), (i % 10) == 0);
|
||||
CHECK_IFF(smap.find(i) != smap.end() && smap.find(i)->second == i+1,
|
||||
(i % 10) == 0);
|
||||
CHECK_IFF(dset.find(i) != dset.end(), (i % 10) == 5);
|
||||
CHECK_IFF(dmap.find(i) != dmap.end(), (i % 10) == 5);
|
||||
CHECK_IFF(dmap.find(i) != dmap.end() && dmap.find(i)->second == i+1,
|
||||
(i % 10) == 5);
|
||||
}
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
106
BeefySysLib/third_party/sparsehash/simple_test.cc
vendored
Normal file
106
BeefySysLib/third_party/sparsehash/simple_test.cc
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright (c) 2007, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// This tests mostly that we can #include the files correctly
|
||||
// and have them work. This unittest purposefully does not
|
||||
// #include <config.h>; it's meant to emulate what a 'regular
|
||||
// install' of sparsehash would be able to see.
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <sparsehash/sparse_hash_set>
|
||||
#include <sparsehash/sparse_hash_map>
|
||||
#include <sparsehash/dense_hash_set>
|
||||
#include <sparsehash/dense_hash_map>
|
||||
#include <sparsehash/template_util.h>
|
||||
#include <sparsehash/type_traits.h>
|
||||
|
||||
#define CHECK_IFF(cond, when) do { \
|
||||
if (when) { \
|
||||
if (!(cond)) { \
|
||||
puts("ERROR: " #cond " failed when " #when " is true\n"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} else { \
|
||||
if (cond) { \
|
||||
puts("ERROR: " #cond " succeeded when " #when " is false\n"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main(int argc, char**) {
|
||||
// Run with an argument to get verbose output
|
||||
const bool verbose = argc > 1;
|
||||
|
||||
google::sparse_hash_set<int> sset;
|
||||
google::sparse_hash_map<int, int> smap;
|
||||
google::dense_hash_set<int> dset;
|
||||
google::dense_hash_map<int, int> dmap;
|
||||
dset.set_empty_key(-1);
|
||||
dmap.set_empty_key(-1);
|
||||
|
||||
for (int i = 0; i < 100; i += 10) { // go by tens
|
||||
sset.insert(i);
|
||||
smap[i] = i+1;
|
||||
dset.insert(i + 5);
|
||||
dmap[i+5] = i+6;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
for (google::sparse_hash_set<int>::const_iterator it = sset.begin();
|
||||
it != sset.end(); ++it)
|
||||
printf("sset: %d\n", *it);
|
||||
for (google::sparse_hash_map<int,int>::const_iterator it = smap.begin();
|
||||
it != smap.end(); ++it)
|
||||
printf("smap: %d -> %d\n", it->first, it->second);
|
||||
for (google::dense_hash_set<int>::const_iterator it = dset.begin();
|
||||
it != dset.end(); ++it)
|
||||
printf("dset: %d\n", *it);
|
||||
for (google::dense_hash_map<int,int>::const_iterator it = dmap.begin();
|
||||
it != dmap.end(); ++it)
|
||||
printf("dmap: %d -> %d\n", it->first, it->second);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
CHECK_IFF(sset.find(i) != sset.end(), (i % 10) == 0);
|
||||
CHECK_IFF(smap.find(i) != smap.end(), (i % 10) == 0);
|
||||
CHECK_IFF(smap.find(i) != smap.end() && smap.find(i)->second == i+1,
|
||||
(i % 10) == 0);
|
||||
CHECK_IFF(dset.find(i) != dset.end(), (i % 10) == 5);
|
||||
CHECK_IFF(dmap.find(i) != dmap.end(), (i % 10) == 5);
|
||||
CHECK_IFF(dmap.find(i) != dmap.end() && dmap.find(i)->second == i+1,
|
||||
(i % 10) == 5);
|
||||
}
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
369
BeefySysLib/third_party/sparsehash/sparsehash/dense_hash_map
vendored
Normal file
369
BeefySysLib/third_party/sparsehash/sparsehash/dense_hash_map
vendored
Normal file
|
@ -0,0 +1,369 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ----
|
||||
//
|
||||
// This is just a very thin wrapper over densehashtable.h, just
|
||||
// like sgi stl's stl_hash_map is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// NOTE: this is exactly like sparse_hash_map.h, with the word
|
||||
// "sparse" replaced by "dense", except for the addition of
|
||||
// set_empty_key().
|
||||
//
|
||||
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
|
||||
//
|
||||
// Otherwise your program will die in mysterious ways. (Note if you
|
||||
// use the constructor that takes an InputIterator range, you pass in
|
||||
// the empty key in the constructor, rather than after. As a result,
|
||||
// this constructor differs from the standard STL version.)
|
||||
//
|
||||
// In other respects, we adhere mostly to the STL semantics for
|
||||
// hash-map. One important exception is that insert() may invalidate
|
||||
// iterators entirely -- STL semantics are that insert() may reorder
|
||||
// iterators, but they all still refer to something valid in the
|
||||
// hashtable. Not so for us. Likewise, insert() may invalidate
|
||||
// pointers into the hashtable. (Whether insert invalidates iterators
|
||||
// and pointers depends on whether it results in a hashtable resize).
|
||||
// On the plus side, delete() doesn't invalidate iterators or pointers
|
||||
// at all, or even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// If you want to use erase() you *must* call set_deleted_key(),
|
||||
// in addition to set_empty_key(), after construction.
|
||||
// The deleted and empty keys must differ.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
// For tr1 compatibility, this can also be called as rehash(0).
|
||||
//
|
||||
// 3) min_load_factor(0.0)
|
||||
// Setting the minimum load factor to 0.0 guarantees that
|
||||
// the hash table will never shrink.
|
||||
//
|
||||
// Roughly speaking:
|
||||
// (1) dense_hash_map: fastest, uses the most memory unless entries are small
|
||||
// (2) sparse_hash_map: slowest, uses the least memory
|
||||
// (3) hash_map / unordered_map (STL): in the middle
|
||||
//
|
||||
// Typically I use sparse_hash_map when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_map otherwise. I
|
||||
// don't personally use dense_hash_set ever; some people use it for
|
||||
// small sets with lots of lookups.
|
||||
//
|
||||
// - dense_hash_map has, typically, about 78% memory overhead (if your
|
||||
// data takes up X bytes, the hash_map uses .78X more bytes in overhead).
|
||||
// - sparse_hash_map has about 4 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-*/dense_hash_map.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _DENSE_HASH_MAP_H_
|
||||
#define _DENSE_HASH_MAP_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <algorithm> // needed by stl_alloc
|
||||
#include <functional> // for equal_to<>, select1st<>, etc
|
||||
#include <memory> // for alloc
|
||||
#include <utility> // for pair<>
|
||||
#include <sparsehash/internal/densehashtable.h> // IWYU pragma: export
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
||||
#include HASH_FUN_H // for hash<>
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <class Key, class T,
|
||||
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
|
||||
class EqualKey = std::equal_to<Key>,
|
||||
class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
|
||||
class dense_hash_map {
|
||||
private:
|
||||
// Apparently select1st is not stl-standard, so we define our own
|
||||
struct SelectKey {
|
||||
typedef const Key& result_type;
|
||||
const Key& operator()(const std::pair<const Key, T>& p) const {
|
||||
return p.first;
|
||||
}
|
||||
};
|
||||
struct SetKey {
|
||||
void operator()(std::pair<const Key, T>* value, const Key& new_key) const {
|
||||
*const_cast<Key*>(&value->first) = new_key;
|
||||
// It would be nice to clear the rest of value here as well, in
|
||||
// case it's taking up a lot of memory. We do this by clearing
|
||||
// the value. This assumes T has a zero-arg constructor!
|
||||
value->second = T();
|
||||
}
|
||||
};
|
||||
// For operator[].
|
||||
struct DefaultValue {
|
||||
std::pair<const Key, T> operator()(const Key& key) {
|
||||
return std::make_pair(key, T());
|
||||
}
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef dense_hashtable<std::pair<const Key, T>, Key, HashFcn, SelectKey,
|
||||
SetKey, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef T data_type;
|
||||
typedef T mapped_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
typedef typename ht::local_iterator local_iterator;
|
||||
typedef typename ht::const_local_iterator const_local_iterator;
|
||||
|
||||
// Iterator functions
|
||||
iterator begin() { return rep.begin(); }
|
||||
iterator end() { return rep.end(); }
|
||||
const_iterator begin() const { return rep.begin(); }
|
||||
const_iterator end() const { return rep.end(); }
|
||||
|
||||
|
||||
// These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
|
||||
local_iterator begin(size_type i) { return rep.begin(i); }
|
||||
local_iterator end(size_type i) { return rep.end(i); }
|
||||
const_local_iterator begin(size_type i) const { return rep.begin(i); }
|
||||
const_local_iterator end(size_type i) const { return rep.end(i); }
|
||||
|
||||
// Accessor functions
|
||||
allocator_type get_allocator() const { return rep.get_allocator(); }
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
hasher hash_function() const { return hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit dense_hash_map(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
dense_hash_map(InputIterator f, InputIterator l,
|
||||
const key_type& empty_key_val,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
|
||||
set_empty_key(empty_key_val);
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
// This clears the hash map without resizing it down to the minimum
|
||||
// bucket count, but rather keeps the number of buckets constant
|
||||
void clear_no_resize() { rep.clear_no_resize(); }
|
||||
void swap(dense_hash_map& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
// These are tr1 methods. bucket() is the bucket the key is or would be in.
|
||||
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
|
||||
size_type bucket(const key_type& key) const { return rep.bucket(key); }
|
||||
float load_factor() const {
|
||||
return size() * 1.0f / bucket_count();
|
||||
}
|
||||
float max_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return grow;
|
||||
}
|
||||
void max_load_factor(float new_grow) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(shrink, new_grow);
|
||||
}
|
||||
// These aren't tr1 methods but perhaps ought to be.
|
||||
float min_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return shrink;
|
||||
}
|
||||
void min_load_factor(float new_shrink) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(new_shrink, grow);
|
||||
}
|
||||
// Deprecated; use min_load_factor() or max_load_factor() instead.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
void rehash(size_type hint) { resize(hint); } // the tr1 name
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) { return rep.find(key); }
|
||||
const_iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
data_type& operator[](const key_type& key) { // This is our value-add!
|
||||
// If key is in the hashtable, returns find(key)->second,
|
||||
// otherwise returns insert(value_type(key, T()).first->second.
|
||||
// Note it does not create an empty T unless the find fails.
|
||||
return rep.template find_or_insert<DefaultValue>(key).second;
|
||||
}
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key)
|
||||
const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
|
||||
// Insertion routines
|
||||
std::pair<iterator, bool> insert(const value_type& obj) {
|
||||
return rep.insert(obj);
|
||||
}
|
||||
template <class InputIterator> void insert(InputIterator f, InputIterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
void insert(const_iterator f, const_iterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// Required for std::insert_iterator; the passed-in iterator is ignored.
|
||||
iterator insert(iterator, const value_type& obj) {
|
||||
return insert(obj).first;
|
||||
}
|
||||
|
||||
// Deletion and empty routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted and empty buckets. You can change the
|
||||
// deleted key as time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_empty_key(const key_type& key) { // YOU MUST CALL THIS!
|
||||
rep.set_empty_key(value_type(key, data_type())); // rep wants a value
|
||||
}
|
||||
key_type empty_key() const {
|
||||
return rep.empty_key().first; // rep returns a value
|
||||
}
|
||||
|
||||
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
key_type deleted_key() const { return rep.deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const dense_hash_map& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const dense_hash_map& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing hash map to disk
|
||||
//
|
||||
// For maximum flexibility, this does not assume a particular
|
||||
// file type (though it will probably be a FILE *). We just pass
|
||||
// the fp through to rep.
|
||||
|
||||
// If your keys and values are simple enough, you can pass this
|
||||
// serializer to serialize()/unserialize(). "Simple enough" means
|
||||
// value_type is a POD type that contains no pointers. Note,
|
||||
// however, we don't try to normalize endianness.
|
||||
typedef typename ht::NopointerSerializer NopointerSerializer;
|
||||
|
||||
// serializer: a class providing operator()(OUTPUT*, const value_type&)
|
||||
// (writing value_type to OUTPUT). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
|
||||
// pointer to a class providing size_t Write(const void*, size_t),
|
||||
// which writes a buffer into a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully written.
|
||||
// Note basic_ostream<not_char> is not currently supported.
|
||||
template <typename ValueSerializer, typename OUTPUT>
|
||||
bool serialize(ValueSerializer serializer, OUTPUT* fp) {
|
||||
return rep.serialize(serializer, fp);
|
||||
}
|
||||
|
||||
// serializer: a functor providing operator()(INPUT*, value_type*)
|
||||
// (reading from INPUT and into value_type). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
|
||||
// pointer to a class providing size_t Read(void*, size_t),
|
||||
// which reads into a buffer from a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully read.
|
||||
// Note basic_istream<not_char> is not currently supported.
|
||||
// NOTE: Since value_type is std::pair<const Key, T>, ValueSerializer
|
||||
// may need to do a const cast in order to fill in the key.
|
||||
template <typename ValueSerializer, typename INPUT>
|
||||
bool unserialize(ValueSerializer serializer, INPUT* fp) {
|
||||
return rep.unserialize(serializer, fp);
|
||||
}
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
|
||||
dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
|
||||
hm1.swap(hm2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _DENSE_HASH_MAP_H_ */
|
338
BeefySysLib/third_party/sparsehash/sparsehash/dense_hash_set
vendored
Normal file
338
BeefySysLib/third_party/sparsehash/sparsehash/dense_hash_set
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// This is just a very thin wrapper over densehashtable.h, just
|
||||
// like sgi stl's stl_hash_set is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// This is more different from dense_hash_map than you might think,
|
||||
// because all iterators for sets are const (you obviously can't
|
||||
// change the key, and for sets there is no value).
|
||||
//
|
||||
// NOTE: this is exactly like sparse_hash_set.h, with the word
|
||||
// "sparse" replaced by "dense", except for the addition of
|
||||
// set_empty_key().
|
||||
//
|
||||
// YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
|
||||
//
|
||||
// Otherwise your program will die in mysterious ways. (Note if you
|
||||
// use the constructor that takes an InputIterator range, you pass in
|
||||
// the empty key in the constructor, rather than after. As a result,
|
||||
// this constructor differs from the standard STL version.)
|
||||
//
|
||||
// In other respects, we adhere mostly to the STL semantics for
|
||||
// hash-map. One important exception is that insert() may invalidate
|
||||
// iterators entirely -- STL semantics are that insert() may reorder
|
||||
// iterators, but they all still refer to something valid in the
|
||||
// hashtable. Not so for us. Likewise, insert() may invalidate
|
||||
// pointers into the hashtable. (Whether insert invalidates iterators
|
||||
// and pointers depends on whether it results in a hashtable resize).
|
||||
// On the plus side, delete() doesn't invalidate iterators or pointers
|
||||
// at all, or even change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// If you want to use erase() you must call set_deleted_key(),
|
||||
// in addition to set_empty_key(), after construction.
|
||||
// The deleted and empty keys must differ.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
// For tr1 compatibility, this can also be called as rehash(0).
|
||||
//
|
||||
// 3) min_load_factor(0.0)
|
||||
// Setting the minimum load factor to 0.0 guarantees that
|
||||
// the hash table will never shrink.
|
||||
//
|
||||
// Roughly speaking:
|
||||
// (1) dense_hash_set: fastest, uses the most memory unless entries are small
|
||||
// (2) sparse_hash_set: slowest, uses the least memory
|
||||
// (3) hash_set / unordered_set (STL): in the middle
|
||||
//
|
||||
// Typically I use sparse_hash_set when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_set otherwise. I
|
||||
// don't personally use dense_hash_set ever; some people use it for
|
||||
// small sets with lots of lookups.
|
||||
//
|
||||
// - dense_hash_set has, typically, about 78% memory overhead (if your
|
||||
// data takes up X bytes, the hash_set uses .78X more bytes in overhead).
|
||||
// - sparse_hash_set has about 4 bits overhead per entry.
|
||||
// - sparse_hash_set can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-*/dense_hash_set.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _DENSE_HASH_SET_H_
|
||||
#define _DENSE_HASH_SET_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <algorithm> // needed by stl_alloc
|
||||
#include <functional> // for equal_to<>, select1st<>, etc
|
||||
#include <memory> // for alloc
|
||||
#include <utility> // for pair<>
|
||||
#include <sparsehash/internal/densehashtable.h> // IWYU pragma: export
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
||||
#include HASH_FUN_H // for hash<>
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <class Value,
|
||||
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
|
||||
class EqualKey = std::equal_to<Value>,
|
||||
class Alloc = libc_allocator_with_realloc<Value> >
|
||||
class dense_hash_set {
|
||||
private:
|
||||
// Apparently identity is not stl-standard, so we define our own
|
||||
struct Identity {
|
||||
typedef const Value& result_type;
|
||||
const Value& operator()(const Value& v) const { return v; }
|
||||
};
|
||||
struct SetKey {
|
||||
void operator()(Value* value, const Value& new_key) const {
|
||||
*value = new_key;
|
||||
}
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef dense_hashtable<Value, Value, HashFcn, Identity, SetKey,
|
||||
EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::const_pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::const_reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::const_iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
typedef typename ht::const_local_iterator local_iterator;
|
||||
typedef typename ht::const_local_iterator const_local_iterator;
|
||||
|
||||
|
||||
// Iterator functions -- recall all iterators are const
|
||||
iterator begin() const { return rep.begin(); }
|
||||
iterator end() const { return rep.end(); }
|
||||
|
||||
// These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
|
||||
local_iterator begin(size_type i) const { return rep.begin(i); }
|
||||
local_iterator end(size_type i) const { return rep.end(i); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
allocator_type get_allocator() const { return rep.get_allocator(); }
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
hasher hash_function() const { return hash_funct(); } // tr1 name
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit dense_hash_set(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
dense_hash_set(InputIterator f, InputIterator l,
|
||||
const key_type& empty_key_val,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
|
||||
set_empty_key(empty_key_val);
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
// This clears the hash set without resizing it down to the minimum
|
||||
// bucket count, but rather keeps the number of buckets constant
|
||||
void clear_no_resize() { rep.clear_no_resize(); }
|
||||
void swap(dense_hash_set& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
// These are tr1 methods. bucket() is the bucket the key is or would be in.
|
||||
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
|
||||
size_type bucket(const key_type& key) const { return rep.bucket(key); }
|
||||
float load_factor() const {
|
||||
return size() * 1.0f / bucket_count();
|
||||
}
|
||||
float max_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return grow;
|
||||
}
|
||||
void max_load_factor(float new_grow) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(shrink, new_grow);
|
||||
}
|
||||
// These aren't tr1 methods but perhaps ought to be.
|
||||
float min_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return shrink;
|
||||
}
|
||||
void min_load_factor(float new_shrink) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(new_shrink, grow);
|
||||
}
|
||||
// Deprecated; use min_load_factor() or max_load_factor() instead.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
void rehash(size_type hint) { resize(hint); } // the tr1 name
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
|
||||
// Insertion routines
|
||||
std::pair<iterator, bool> insert(const value_type& obj) {
|
||||
std::pair<typename ht::iterator, bool> p = rep.insert(obj);
|
||||
return std::pair<iterator, bool>(p.first, p.second); // const to non-const
|
||||
}
|
||||
template <class InputIterator> void insert(InputIterator f, InputIterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
void insert(const_iterator f, const_iterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// Required for std::insert_iterator; the passed-in iterator is ignored.
|
||||
iterator insert(iterator, const value_type& obj) {
|
||||
return insert(obj).first;
|
||||
}
|
||||
|
||||
// Deletion and empty routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted and empty buckets. You can change the
|
||||
// deleted key as time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_empty_key(const key_type& key) { rep.set_empty_key(key); }
|
||||
key_type empty_key() const { return rep.empty_key(); }
|
||||
|
||||
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
key_type deleted_key() const { return rep.deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const dense_hash_set& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const dense_hash_set& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
//
|
||||
// For maximum flexibility, this does not assume a particular
|
||||
// file type (though it will probably be a FILE *). We just pass
|
||||
// the fp through to rep.
|
||||
|
||||
// If your keys and values are simple enough, you can pass this
|
||||
// serializer to serialize()/unserialize(). "Simple enough" means
|
||||
// value_type is a POD type that contains no pointers. Note,
|
||||
// however, we don't try to normalize endianness.
|
||||
typedef typename ht::NopointerSerializer NopointerSerializer;
|
||||
|
||||
// serializer: a class providing operator()(OUTPUT*, const value_type&)
|
||||
// (writing value_type to OUTPUT). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
|
||||
// pointer to a class providing size_t Write(const void*, size_t),
|
||||
// which writes a buffer into a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully written.
|
||||
// Note basic_ostream<not_char> is not currently supported.
|
||||
template <typename ValueSerializer, typename OUTPUT>
|
||||
bool serialize(ValueSerializer serializer, OUTPUT* fp) {
|
||||
return rep.serialize(serializer, fp);
|
||||
}
|
||||
|
||||
// serializer: a functor providing operator()(INPUT*, value_type*)
|
||||
// (reading from INPUT and into value_type). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
|
||||
// pointer to a class providing size_t Read(void*, size_t),
|
||||
// which reads into a buffer from a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully read.
|
||||
// Note basic_istream<not_char> is not currently supported.
|
||||
template <typename ValueSerializer, typename INPUT>
|
||||
bool unserialize(ValueSerializer serializer, INPUT* fp) {
|
||||
return rep.unserialize(serializer, fp);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Val, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
|
||||
dense_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
|
||||
hs1.swap(hs2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _DENSE_HASH_SET_H_ */
|
1327
BeefySysLib/third_party/sparsehash/sparsehash/internal/densehashtable.h
vendored
Normal file
1327
BeefySysLib/third_party/sparsehash/sparsehash/internal/densehashtable.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
381
BeefySysLib/third_party/sparsehash/sparsehash/internal/hashtable-common.h
vendored
Normal file
381
BeefySysLib/third_party/sparsehash/sparsehash/internal/hashtable-common.h
vendored
Normal file
|
@ -0,0 +1,381 @@
|
|||
// Copyright (c) 2010, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// Provides classes shared by both sparse and dense hashtable.
|
||||
//
|
||||
// sh_hashtable_settings has parameters for growing and shrinking
|
||||
// a hashtable. It also packages zero-size functor (ie. hasher).
|
||||
//
|
||||
// Other functions and classes provide common code for serializing
|
||||
// and deserializing hashtables to a stream (such as a FILE*).
|
||||
|
||||
#ifndef UTIL_GTL_HASHTABLE_COMMON_H_
|
||||
#define UTIL_GTL_HASHTABLE_COMMON_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h> // for size_t
|
||||
#include <iosfwd>
|
||||
#include <stdexcept> // For length_error
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <bool> struct SparsehashCompileAssert { };
|
||||
#define SPARSEHASH_COMPILE_ASSERT(expr, msg) \
|
||||
__attribute__((unused)) typedef SparsehashCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
|
||||
|
||||
namespace sparsehash_internal {
|
||||
|
||||
// Adaptor methods for reading/writing data from an INPUT or OUPTUT
|
||||
// variable passed to serialize() or unserialize(). For now we
|
||||
// have implemented INPUT/OUTPUT for FILE*, istream*/ostream* (note
|
||||
// they are pointers, unlike typical use), or else a pointer to
|
||||
// something that supports a Read()/Write() method.
|
||||
//
|
||||
// For technical reasons, we implement read_data/write_data in two
|
||||
// stages. The actual work is done in *_data_internal, which takes
|
||||
// the stream argument twice: once as a template type, and once with
|
||||
// normal type information. (We only use the second version.) We do
|
||||
// this because of how C++ picks what function overload to use. If we
|
||||
// implemented this the naive way:
|
||||
// bool read_data(istream* is, const void* data, size_t length);
|
||||
// template<typename T> read_data(T* fp, const void* data, size_t length);
|
||||
// C++ would prefer the second version for every stream type except
|
||||
// istream. However, we want C++ to prefer the first version for
|
||||
// streams that are *subclasses* of istream, such as istringstream.
|
||||
// This is not possible given the way template types are resolved. So
|
||||
// we split the stream argument in two, one of which is templated and
|
||||
// one of which is not. The specialized functions (like the istream
|
||||
// version above) ignore the template arg and use the second, 'type'
|
||||
// arg, getting subclass matching as normal. The 'catch-all'
|
||||
// functions (the second version above) use the template arg to deduce
|
||||
// the type, and use a second, void* arg to achieve the desired
|
||||
// 'catch-all' semantics.
|
||||
|
||||
// ----- low-level I/O for FILE* ----
|
||||
|
||||
template<typename Ignored>
|
||||
inline bool read_data_internal(Ignored*, FILE* fp,
|
||||
void* data, size_t length) {
|
||||
return fread(data, length, 1, fp) == 1;
|
||||
}
|
||||
|
||||
template<typename Ignored>
|
||||
inline bool write_data_internal(Ignored*, FILE* fp,
|
||||
const void* data, size_t length) {
|
||||
return fwrite(data, length, 1, fp) == 1;
|
||||
}
|
||||
|
||||
// ----- low-level I/O for iostream ----
|
||||
|
||||
// We want the caller to be responsible for #including <iostream>, not
|
||||
// us, because iostream is a big header! According to the standard,
|
||||
// it's only legal to delay the instantiation the way we want to if
|
||||
// the istream/ostream is a template type. So we jump through hoops.
|
||||
template<typename ISTREAM>
|
||||
inline bool read_data_internal_for_istream(ISTREAM* fp,
|
||||
void* data, size_t length) {
|
||||
return fp->read(reinterpret_cast<char*>(data), length).good();
|
||||
}
|
||||
template<typename Ignored>
|
||||
inline bool read_data_internal(Ignored*, std::istream* fp,
|
||||
void* data, size_t length) {
|
||||
return read_data_internal_for_istream(fp, data, length);
|
||||
}
|
||||
|
||||
template<typename OSTREAM>
|
||||
inline bool write_data_internal_for_ostream(OSTREAM* fp,
|
||||
const void* data, size_t length) {
|
||||
return fp->write(reinterpret_cast<const char*>(data), length).good();
|
||||
}
|
||||
template<typename Ignored>
|
||||
inline bool write_data_internal(Ignored*, std::ostream* fp,
|
||||
const void* data, size_t length) {
|
||||
return write_data_internal_for_ostream(fp, data, length);
|
||||
}
|
||||
|
||||
// ----- low-level I/O for custom streams ----
|
||||
|
||||
// The INPUT type needs to support a Read() method that takes a
|
||||
// buffer and a length and returns the number of bytes read.
|
||||
template <typename INPUT>
|
||||
inline bool read_data_internal(INPUT* fp, void*,
|
||||
void* data, size_t length) {
|
||||
return static_cast<size_t>(fp->Read(data, length)) == length;
|
||||
}
|
||||
|
||||
// The OUTPUT type needs to support a Write() operation that takes
|
||||
// a buffer and a length and returns the number of bytes written.
|
||||
template <typename OUTPUT>
|
||||
inline bool write_data_internal(OUTPUT* fp, void*,
|
||||
const void* data, size_t length) {
|
||||
return static_cast<size_t>(fp->Write(data, length)) == length;
|
||||
}
|
||||
|
||||
// ----- low-level I/O: the public API ----
|
||||
|
||||
template <typename INPUT>
|
||||
inline bool read_data(INPUT* fp, void* data, size_t length) {
|
||||
return read_data_internal(fp, fp, data, length);
|
||||
}
|
||||
|
||||
template <typename OUTPUT>
|
||||
inline bool write_data(OUTPUT* fp, const void* data, size_t length) {
|
||||
return write_data_internal(fp, fp, data, length);
|
||||
}
|
||||
|
||||
// Uses read_data() and write_data() to read/write an integer.
|
||||
// length is the number of bytes to read/write (which may differ
|
||||
// from sizeof(IntType), allowing us to save on a 32-bit system
|
||||
// and load on a 64-bit system). Excess bytes are taken to be 0.
|
||||
// INPUT and OUTPUT must match legal inputs to read/write_data (above).
|
||||
template <typename INPUT, typename IntType>
|
||||
bool read_bigendian_number(INPUT* fp, IntType* value, size_t length) {
|
||||
*value = 0;
|
||||
unsigned char byte;
|
||||
// We require IntType to be unsigned or else the shifting gets all screwy.
|
||||
SPARSEHASH_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0),
|
||||
serializing_int_requires_an_unsigned_type);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
if (!read_data(fp, &byte, sizeof(byte))) return false;
|
||||
*value |= static_cast<IntType>(byte) << ((length - 1 - i) * 8);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename OUTPUT, typename IntType>
|
||||
bool write_bigendian_number(OUTPUT* fp, IntType value, size_t length) {
|
||||
unsigned char byte;
|
||||
// We require IntType to be unsigned or else the shifting gets all screwy.
|
||||
SPARSEHASH_COMPILE_ASSERT(static_cast<IntType>(-1) > static_cast<IntType>(0),
|
||||
serializing_int_requires_an_unsigned_type);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
byte = (sizeof(value) <= length-1 - i)
|
||||
? 0 : static_cast<unsigned char>((value >> ((length-1 - i) * 8)) & 255);
|
||||
if (!write_data(fp, &byte, sizeof(byte))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// If your keys and values are simple enough, you can pass this
|
||||
// serializer to serialize()/unserialize(). "Simple enough" means
|
||||
// value_type is a POD type that contains no pointers. Note,
|
||||
// however, we don't try to normalize endianness.
|
||||
// This is the type used for NopointerSerializer.
|
||||
template <typename value_type> struct pod_serializer {
|
||||
template <typename INPUT>
|
||||
bool operator()(INPUT* fp, value_type* value) const {
|
||||
return read_data(fp, value, sizeof(*value));
|
||||
}
|
||||
|
||||
template <typename OUTPUT>
|
||||
bool operator()(OUTPUT* fp, const value_type& value) const {
|
||||
return write_data(fp, &value, sizeof(value));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Settings contains parameters for growing and shrinking the table.
|
||||
// It also packages zero-size functor (ie. hasher).
|
||||
//
|
||||
// It does some munging of the hash value in cases where we think
|
||||
// (fear) the original hash function might not be very good. In
|
||||
// particular, the default hash of pointers is the identity hash,
|
||||
// so probably all the low bits are 0. We identify when we think
|
||||
// we're hashing a pointer, and chop off the low bits. Note this
|
||||
// isn't perfect: even when the key is a pointer, we can't tell
|
||||
// for sure that the hash is the identity hash. If it's not, this
|
||||
// is needless work (and possibly, though not likely, harmful).
|
||||
|
||||
template<typename Key, typename HashFunc,
|
||||
typename SizeType, int HT_MIN_BUCKETS>
|
||||
class sh_hashtable_settings : public HashFunc {
|
||||
public:
|
||||
typedef Key key_type;
|
||||
typedef HashFunc hasher;
|
||||
typedef SizeType size_type;
|
||||
|
||||
public:
|
||||
sh_hashtable_settings(const hasher& hf,
|
||||
const float ht_occupancy_flt,
|
||||
const float ht_empty_flt)
|
||||
: hasher(hf),
|
||||
enlarge_threshold_(0),
|
||||
shrink_threshold_(0),
|
||||
consider_shrink_(false),
|
||||
use_empty_(false),
|
||||
use_deleted_(false),
|
||||
num_ht_copies_(0) {
|
||||
set_enlarge_factor(ht_occupancy_flt);
|
||||
set_shrink_factor(ht_empty_flt);
|
||||
}
|
||||
|
||||
size_type hash(const key_type& v) const {
|
||||
// We munge the hash value when we don't trust hasher::operator().
|
||||
return hash_munger<Key>::MungedHash(hasher::operator()(v));
|
||||
}
|
||||
|
||||
float enlarge_factor() const {
|
||||
return enlarge_factor_;
|
||||
}
|
||||
void set_enlarge_factor(float f) {
|
||||
enlarge_factor_ = f;
|
||||
}
|
||||
float shrink_factor() const {
|
||||
return shrink_factor_;
|
||||
}
|
||||
void set_shrink_factor(float f) {
|
||||
shrink_factor_ = f;
|
||||
}
|
||||
|
||||
size_type enlarge_threshold() const {
|
||||
return enlarge_threshold_;
|
||||
}
|
||||
void set_enlarge_threshold(size_type t) {
|
||||
enlarge_threshold_ = t;
|
||||
}
|
||||
size_type shrink_threshold() const {
|
||||
return shrink_threshold_;
|
||||
}
|
||||
void set_shrink_threshold(size_type t) {
|
||||
shrink_threshold_ = t;
|
||||
}
|
||||
|
||||
size_type enlarge_size(size_type x) const {
|
||||
return static_cast<size_type>(x * enlarge_factor_);
|
||||
}
|
||||
size_type shrink_size(size_type x) const {
|
||||
return static_cast<size_type>(x * shrink_factor_);
|
||||
}
|
||||
|
||||
bool consider_shrink() const {
|
||||
return consider_shrink_;
|
||||
}
|
||||
void set_consider_shrink(bool t) {
|
||||
consider_shrink_ = t;
|
||||
}
|
||||
|
||||
bool use_empty() const {
|
||||
return use_empty_;
|
||||
}
|
||||
void set_use_empty(bool t) {
|
||||
use_empty_ = t;
|
||||
}
|
||||
|
||||
bool use_deleted() const {
|
||||
return use_deleted_;
|
||||
}
|
||||
void set_use_deleted(bool t) {
|
||||
use_deleted_ = t;
|
||||
}
|
||||
|
||||
size_type num_ht_copies() const {
|
||||
return static_cast<size_type>(num_ht_copies_);
|
||||
}
|
||||
void inc_num_ht_copies() {
|
||||
++num_ht_copies_;
|
||||
}
|
||||
|
||||
// Reset the enlarge and shrink thresholds
|
||||
void reset_thresholds(size_type num_buckets) {
|
||||
set_enlarge_threshold(enlarge_size(num_buckets));
|
||||
set_shrink_threshold(shrink_size(num_buckets));
|
||||
// whatever caused us to reset already considered
|
||||
set_consider_shrink(false);
|
||||
}
|
||||
|
||||
// Caller is resposible for calling reset_threshold right after
|
||||
// set_resizing_parameters.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
assert(shrink >= 0.0);
|
||||
assert(grow <= 1.0);
|
||||
if (shrink > grow/2.0f)
|
||||
shrink = grow / 2.0f; // otherwise we thrash hashtable size
|
||||
set_shrink_factor(shrink);
|
||||
set_enlarge_factor(grow);
|
||||
}
|
||||
|
||||
// This is the smallest size a hashtable can be without being too crowded
|
||||
// If you like, you can give a min #buckets as well as a min #elts
|
||||
size_type min_buckets(size_type num_elts, size_type min_buckets_wanted) {
|
||||
float enlarge = enlarge_factor();
|
||||
size_type sz = HT_MIN_BUCKETS; // min buckets allowed
|
||||
while ( sz < min_buckets_wanted ||
|
||||
num_elts >= static_cast<size_type>(sz * enlarge) ) {
|
||||
// This just prevents overflowing size_type, since sz can exceed
|
||||
// max_size() here.
|
||||
if (static_cast<size_type>(sz * 2) < sz) {
|
||||
throw std::length_error("resize overflow"); // protect against overflow
|
||||
}
|
||||
sz *= 2;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
private:
|
||||
template<class HashKey> class hash_munger {
|
||||
public:
|
||||
static size_t MungedHash(size_t hash) {
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
// This matches when the hashtable key is a pointer.
|
||||
template<class HashKey> class hash_munger<HashKey*> {
|
||||
public:
|
||||
static size_t MungedHash(size_t hash) {
|
||||
// TODO(csilvers): consider rotating instead:
|
||||
// static const int shift = (sizeof(void *) == 4) ? 2 : 3;
|
||||
// return (hash << (sizeof(hash) * 8) - shift)) | (hash >> shift);
|
||||
// This matters if we ever change sparse/dense_hash_* to compare
|
||||
// hashes before comparing actual values. It's speedy on x86.
|
||||
return hash / sizeof(void*); // get rid of known-0 bits
|
||||
}
|
||||
};
|
||||
|
||||
size_type enlarge_threshold_; // table.size() * enlarge_factor
|
||||
size_type shrink_threshold_; // table.size() * shrink_factor
|
||||
float enlarge_factor_; // how full before resize
|
||||
float shrink_factor_; // how empty before resize
|
||||
// consider_shrink=true if we should try to shrink before next insert
|
||||
bool consider_shrink_;
|
||||
bool use_empty_; // used only by densehashtable, not sparsehashtable
|
||||
bool use_deleted_; // false until delkey has been set
|
||||
// num_ht_copies is a counter incremented every Copy/Move
|
||||
unsigned int num_ht_copies_;
|
||||
};
|
||||
|
||||
} // namespace sparsehash_internal
|
||||
|
||||
#undef SPARSEHASH_COMPILE_ASSERT
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // UTIL_GTL_HASHTABLE_COMMON_H_
|
119
BeefySysLib/third_party/sparsehash/sparsehash/internal/libc_allocator_with_realloc.h
vendored
Normal file
119
BeefySysLib/third_party/sparsehash/sparsehash/internal/libc_allocator_with_realloc.h
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
// Copyright (c) 2010, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
|
||||
#ifndef UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_
|
||||
#define UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <stdlib.h> // for malloc/realloc/free
|
||||
#include <stddef.h> // for ptrdiff_t
|
||||
#include <new> // for placement new
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template<class T>
|
||||
class libc_allocator_with_realloc {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
|
||||
libc_allocator_with_realloc() {}
|
||||
libc_allocator_with_realloc(const libc_allocator_with_realloc&) {}
|
||||
~libc_allocator_with_realloc() {}
|
||||
|
||||
pointer address(reference r) const { return &r; }
|
||||
const_pointer address(const_reference r) const { return &r; }
|
||||
|
||||
pointer allocate(size_type n, const_pointer = 0) {
|
||||
return static_cast<pointer>(malloc(n * sizeof(value_type)));
|
||||
}
|
||||
void deallocate(pointer p, size_type) {
|
||||
free(p);
|
||||
}
|
||||
pointer reallocate(pointer p, size_type n) {
|
||||
return static_cast<pointer>(realloc(p, n * sizeof(value_type)));
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return static_cast<size_type>(-1) / sizeof(value_type);
|
||||
}
|
||||
|
||||
void construct(pointer p, const value_type& val) {
|
||||
new(p) value_type(val);
|
||||
}
|
||||
void destroy(pointer p) { p->~value_type(); }
|
||||
|
||||
template <class U>
|
||||
libc_allocator_with_realloc(const libc_allocator_with_realloc<U>&) {}
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef libc_allocator_with_realloc<U> other;
|
||||
};
|
||||
};
|
||||
|
||||
// libc_allocator_with_realloc<void> specialization.
|
||||
template<>
|
||||
class libc_allocator_with_realloc<void> {
|
||||
public:
|
||||
typedef void value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef libc_allocator_with_realloc<U> other;
|
||||
};
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(const libc_allocator_with_realloc<T>&,
|
||||
const libc_allocator_with_realloc<T>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool operator!=(const libc_allocator_with_realloc<T>&,
|
||||
const libc_allocator_with_realloc<T>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // UTIL_GTL_LIBC_ALLOCATOR_WITH_REALLOC_H_
|
1247
BeefySysLib/third_party/sparsehash/sparsehash/internal/sparsehashtable.h
vendored
Normal file
1247
BeefySysLib/third_party/sparsehash/sparsehash/internal/sparsehashtable.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
363
BeefySysLib/third_party/sparsehash/sparsehash/sparse_hash_map
vendored
Normal file
363
BeefySysLib/third_party/sparsehash/sparsehash/sparse_hash_map
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// This is just a very thin wrapper over sparsehashtable.h, just
|
||||
// like sgi stl's stl_hash_map is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// We adhere mostly to the STL semantics for hash-map. One important
|
||||
// exception is that insert() may invalidate iterators entirely -- STL
|
||||
// semantics are that insert() may reorder iterators, but they all
|
||||
// still refer to something valid in the hashtable. Not so for us.
|
||||
// Likewise, insert() may invalidate pointers into the hashtable.
|
||||
// (Whether insert invalidates iterators and pointers depends on
|
||||
// whether it results in a hashtable resize). On the plus side,
|
||||
// delete() doesn't invalidate iterators or pointers at all, or even
|
||||
// change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// Unlike STL's hash_map, if you want to use erase() you
|
||||
// *must* call set_deleted_key() after construction.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This is what allows you to iterate over a hashtable
|
||||
// and call erase() without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
// For tr1 compatibility, this can also be called as rehash(0).
|
||||
//
|
||||
// 3) min_load_factor(0.0)
|
||||
// Setting the minimum load factor to 0.0 guarantees that
|
||||
// the hash table will never shrink.
|
||||
//
|
||||
// Roughly speaking:
|
||||
// (1) dense_hash_map: fastest, uses the most memory unless entries are small
|
||||
// (2) sparse_hash_map: slowest, uses the least memory
|
||||
// (3) hash_map / unordered_map (STL): in the middle
|
||||
//
|
||||
// Typically I use sparse_hash_map when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_map otherwise. I
|
||||
// don't personally use dense_hash_map ever; some people use it for
|
||||
// small maps with lots of lookups.
|
||||
//
|
||||
// - dense_hash_map has, typically, about 78% memory overhead (if your
|
||||
// data takes up X bytes, the hash_map uses .78X more bytes in overhead).
|
||||
// - sparse_hash_map has about 4 bits overhead per entry.
|
||||
// - sparse_hash_map can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-*/sparse_hash_map.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _SPARSE_HASH_MAP_H_
|
||||
#define _SPARSE_HASH_MAP_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <algorithm> // needed by stl_alloc
|
||||
#include <functional> // for equal_to<>, select1st<>, etc
|
||||
#include <memory> // for alloc
|
||||
#include <utility> // for pair<>
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
||||
#include <sparsehash/internal/sparsehashtable.h> // IWYU pragma: export
|
||||
#include HASH_FUN_H // for hash<>
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <class Key, class T,
|
||||
class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
|
||||
class EqualKey = std::equal_to<Key>,
|
||||
class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
|
||||
class sparse_hash_map {
|
||||
private:
|
||||
// Apparently select1st is not stl-standard, so we define our own
|
||||
struct SelectKey {
|
||||
typedef const Key& result_type;
|
||||
const Key& operator()(const std::pair<const Key, T>& p) const {
|
||||
return p.first;
|
||||
}
|
||||
};
|
||||
struct SetKey {
|
||||
void operator()(std::pair<const Key, T>* value, const Key& new_key) const {
|
||||
*const_cast<Key*>(&value->first) = new_key;
|
||||
// It would be nice to clear the rest of value here as well, in
|
||||
// case it's taking up a lot of memory. We do this by clearing
|
||||
// the value. This assumes T has a zero-arg constructor!
|
||||
value->second = T();
|
||||
}
|
||||
};
|
||||
// For operator[].
|
||||
struct DefaultValue {
|
||||
std::pair<const Key, T> operator()(const Key& key) {
|
||||
return std::make_pair(key, T());
|
||||
}
|
||||
};
|
||||
|
||||
// The actual data
|
||||
typedef sparse_hashtable<std::pair<const Key, T>, Key, HashFcn, SelectKey,
|
||||
SetKey, EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef T data_type;
|
||||
typedef T mapped_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
typedef typename ht::local_iterator local_iterator;
|
||||
typedef typename ht::const_local_iterator const_local_iterator;
|
||||
|
||||
// Iterator functions
|
||||
iterator begin() { return rep.begin(); }
|
||||
iterator end() { return rep.end(); }
|
||||
const_iterator begin() const { return rep.begin(); }
|
||||
const_iterator end() const { return rep.end(); }
|
||||
|
||||
// These come from tr1's unordered_map. For us, a bucket has 0 or 1 elements.
|
||||
local_iterator begin(size_type i) { return rep.begin(i); }
|
||||
local_iterator end(size_type i) { return rep.end(i); }
|
||||
const_local_iterator begin(size_type i) const { return rep.begin(i); }
|
||||
const_local_iterator end(size_type i) const { return rep.end(i); }
|
||||
|
||||
// Accessor functions
|
||||
allocator_type get_allocator() const { return rep.get_allocator(); }
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
hasher hash_function() const { return hash_funct(); }
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit sparse_hash_map(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
sparse_hash_map(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
void swap(sparse_hash_map& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
// These are tr1 methods. bucket() is the bucket the key is or would be in.
|
||||
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
|
||||
size_type bucket(const key_type& key) const { return rep.bucket(key); }
|
||||
float load_factor() const {
|
||||
return size() * 1.0f / bucket_count();
|
||||
}
|
||||
float max_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return grow;
|
||||
}
|
||||
void max_load_factor(float new_grow) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(shrink, new_grow);
|
||||
}
|
||||
// These aren't tr1 methods but perhaps ought to be.
|
||||
float min_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return shrink;
|
||||
}
|
||||
void min_load_factor(float new_shrink) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(new_shrink, grow);
|
||||
}
|
||||
// Deprecated; use min_load_factor() or max_load_factor() instead.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
void rehash(size_type hint) { resize(hint); } // the tr1 name
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) { return rep.find(key); }
|
||||
const_iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
data_type& operator[](const key_type& key) { // This is our value-add!
|
||||
// If key is in the hashtable, returns find(key)->second,
|
||||
// otherwise returns insert(value_type(key, T()).first->second.
|
||||
// Note it does not create an empty T unless the find fails.
|
||||
return rep.template find_or_insert<DefaultValue>(key).second;
|
||||
}
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
std::pair<const_iterator, const_iterator> equal_range(const key_type& key)
|
||||
const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
// Insertion routines
|
||||
std::pair<iterator, bool> insert(const value_type& obj) {
|
||||
return rep.insert(obj);
|
||||
}
|
||||
template <class InputIterator> void insert(InputIterator f, InputIterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
void insert(const_iterator f, const_iterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// Required for std::insert_iterator; the passed-in iterator is ignored.
|
||||
iterator insert(iterator, const value_type& obj) {
|
||||
return insert(obj).first;
|
||||
}
|
||||
|
||||
// Deletion routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted buckets. You can change the key as
|
||||
// time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_deleted_key(const key_type& key) {
|
||||
rep.set_deleted_key(key);
|
||||
}
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
key_type deleted_key() const { return rep.deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const sparse_hash_map& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const sparse_hash_map& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
//
|
||||
// For maximum flexibility, this does not assume a particular
|
||||
// file type (though it will probably be a FILE *). We just pass
|
||||
// the fp through to rep.
|
||||
|
||||
// If your keys and values are simple enough, you can pass this
|
||||
// serializer to serialize()/unserialize(). "Simple enough" means
|
||||
// value_type is a POD type that contains no pointers. Note,
|
||||
// however, we don't try to normalize endianness.
|
||||
typedef typename ht::NopointerSerializer NopointerSerializer;
|
||||
|
||||
// serializer: a class providing operator()(OUTPUT*, const value_type&)
|
||||
// (writing value_type to OUTPUT). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
|
||||
// pointer to a class providing size_t Write(const void*, size_t),
|
||||
// which writes a buffer into a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully written.
|
||||
// Note basic_ostream<not_char> is not currently supported.
|
||||
template <typename ValueSerializer, typename OUTPUT>
|
||||
bool serialize(ValueSerializer serializer, OUTPUT* fp) {
|
||||
return rep.serialize(serializer, fp);
|
||||
}
|
||||
|
||||
// serializer: a functor providing operator()(INPUT*, value_type*)
|
||||
// (reading from INPUT and into value_type). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
|
||||
// pointer to a class providing size_t Read(void*, size_t),
|
||||
// which reads into a buffer from a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully read.
|
||||
// Note basic_istream<not_char> is not currently supported.
|
||||
// NOTE: Since value_type is std::pair<const Key, T>, ValueSerializer
|
||||
// may need to do a const cast in order to fill in the key.
|
||||
// NOTE: if Key or T are not POD types, the serializer MUST use
|
||||
// placement-new to initialize their values, rather than a normal
|
||||
// equals-assignment or similar. (The value_type* passed into the
|
||||
// serializer points to garbage memory.)
|
||||
template <typename ValueSerializer, typename INPUT>
|
||||
bool unserialize(ValueSerializer serializer, INPUT* fp) {
|
||||
return rep.unserialize(serializer, fp);
|
||||
}
|
||||
|
||||
// The four methods below are DEPRECATED.
|
||||
// Use serialize() and unserialize() for new code.
|
||||
template <typename OUTPUT>
|
||||
bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
|
||||
|
||||
template <typename INPUT>
|
||||
bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
|
||||
|
||||
template <typename OUTPUT>
|
||||
bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
|
||||
|
||||
template <typename INPUT>
|
||||
bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
// We need a global swap as well
|
||||
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
|
||||
sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
|
||||
hm1.swap(hm2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _SPARSE_HASH_MAP_H_ */
|
338
BeefySysLib/third_party/sparsehash/sparsehash/sparse_hash_set
vendored
Normal file
338
BeefySysLib/third_party/sparsehash/sparsehash/sparse_hash_set
vendored
Normal file
|
@ -0,0 +1,338 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// This is just a very thin wrapper over sparsehashtable.h, just
|
||||
// like sgi stl's stl_hash_set is a very thin wrapper over
|
||||
// stl_hashtable. The major thing we define is operator[], because
|
||||
// we have a concept of a data_type which stl_hashtable doesn't
|
||||
// (it only has a key and a value).
|
||||
//
|
||||
// This is more different from sparse_hash_map than you might think,
|
||||
// because all iterators for sets are const (you obviously can't
|
||||
// change the key, and for sets there is no value).
|
||||
//
|
||||
// We adhere mostly to the STL semantics for hash-map. One important
|
||||
// exception is that insert() may invalidate iterators entirely -- STL
|
||||
// semantics are that insert() may reorder iterators, but they all
|
||||
// still refer to something valid in the hashtable. Not so for us.
|
||||
// Likewise, insert() may invalidate pointers into the hashtable.
|
||||
// (Whether insert invalidates iterators and pointers depends on
|
||||
// whether it results in a hashtable resize). On the plus side,
|
||||
// delete() doesn't invalidate iterators or pointers at all, or even
|
||||
// change the ordering of elements.
|
||||
//
|
||||
// Here are a few "power user" tips:
|
||||
//
|
||||
// 1) set_deleted_key():
|
||||
// Unlike STL's hash_map, if you want to use erase() you
|
||||
// *must* call set_deleted_key() after construction.
|
||||
//
|
||||
// 2) resize(0):
|
||||
// When an item is deleted, its memory isn't freed right
|
||||
// away. This allows you to iterate over a hashtable,
|
||||
// and call erase(), without invalidating the iterator.
|
||||
// To force the memory to be freed, call resize(0).
|
||||
// For tr1 compatibility, this can also be called as rehash(0).
|
||||
//
|
||||
// 3) min_load_factor(0.0)
|
||||
// Setting the minimum load factor to 0.0 guarantees that
|
||||
// the hash table will never shrink.
|
||||
//
|
||||
// Roughly speaking:
|
||||
// (1) dense_hash_set: fastest, uses the most memory unless entries are small
|
||||
// (2) sparse_hash_set: slowest, uses the least memory
|
||||
// (3) hash_set / unordered_set (STL): in the middle
|
||||
//
|
||||
// Typically I use sparse_hash_set when I care about space and/or when
|
||||
// I need to save the hashtable on disk. I use hash_set otherwise. I
|
||||
// don't personally use dense_hash_set ever; some people use it for
|
||||
// small sets with lots of lookups.
|
||||
//
|
||||
// - dense_hash_set has, typically, about 78% memory overhead (if your
|
||||
// data takes up X bytes, the hash_set uses .78X more bytes in overhead).
|
||||
// - sparse_hash_set has about 4 bits overhead per entry.
|
||||
// - sparse_hash_set can be 3-7 times slower than the others for lookup and,
|
||||
// especially, inserts. See time_hash_map.cc for details.
|
||||
//
|
||||
// See /usr/(local/)?doc/sparsehash-*/sparse_hash_set.html
|
||||
// for information about how to use this class.
|
||||
|
||||
#ifndef _SPARSE_HASH_SET_H_
|
||||
#define _SPARSE_HASH_SET_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <algorithm> // needed by stl_alloc
|
||||
#include <functional> // for equal_to<>
|
||||
#include <memory> // for alloc (which we don't use)
|
||||
#include <utility> // for pair<>
|
||||
#include <sparsehash/internal/libc_allocator_with_realloc.h>
|
||||
#include <sparsehash/internal/sparsehashtable.h> // IWYU pragma: export
|
||||
#include HASH_FUN_H // for hash<>
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <class Value,
|
||||
class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
|
||||
class EqualKey = std::equal_to<Value>,
|
||||
class Alloc = libc_allocator_with_realloc<Value> >
|
||||
class sparse_hash_set {
|
||||
private:
|
||||
// Apparently identity is not stl-standard, so we define our own
|
||||
struct Identity {
|
||||
typedef const Value& result_type;
|
||||
const Value& operator()(const Value& v) const { return v; }
|
||||
};
|
||||
struct SetKey {
|
||||
void operator()(Value* value, const Value& new_key) const {
|
||||
*value = new_key;
|
||||
}
|
||||
};
|
||||
|
||||
typedef sparse_hashtable<Value, Value, HashFcn, Identity, SetKey,
|
||||
EqualKey, Alloc> ht;
|
||||
ht rep;
|
||||
|
||||
public:
|
||||
typedef typename ht::key_type key_type;
|
||||
typedef typename ht::value_type value_type;
|
||||
typedef typename ht::hasher hasher;
|
||||
typedef typename ht::key_equal key_equal;
|
||||
typedef Alloc allocator_type;
|
||||
|
||||
typedef typename ht::size_type size_type;
|
||||
typedef typename ht::difference_type difference_type;
|
||||
typedef typename ht::const_pointer pointer;
|
||||
typedef typename ht::const_pointer const_pointer;
|
||||
typedef typename ht::const_reference reference;
|
||||
typedef typename ht::const_reference const_reference;
|
||||
|
||||
typedef typename ht::const_iterator iterator;
|
||||
typedef typename ht::const_iterator const_iterator;
|
||||
typedef typename ht::const_local_iterator local_iterator;
|
||||
typedef typename ht::const_local_iterator const_local_iterator;
|
||||
|
||||
|
||||
// Iterator functions -- recall all iterators are const
|
||||
iterator begin() const { return rep.begin(); }
|
||||
iterator end() const { return rep.end(); }
|
||||
|
||||
// These come from tr1's unordered_set. For us, a bucket has 0 or 1 elements.
|
||||
local_iterator begin(size_type i) const { return rep.begin(i); }
|
||||
local_iterator end(size_type i) const { return rep.end(i); }
|
||||
|
||||
|
||||
// Accessor functions
|
||||
allocator_type get_allocator() const { return rep.get_allocator(); }
|
||||
hasher hash_funct() const { return rep.hash_funct(); }
|
||||
hasher hash_function() const { return hash_funct(); } // tr1 name
|
||||
key_equal key_eq() const { return rep.key_eq(); }
|
||||
|
||||
|
||||
// Constructors
|
||||
explicit sparse_hash_set(size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
sparse_hash_set(InputIterator f, InputIterator l,
|
||||
size_type expected_max_items_in_table = 0,
|
||||
const hasher& hf = hasher(),
|
||||
const key_equal& eql = key_equal(),
|
||||
const allocator_type& alloc = allocator_type())
|
||||
: rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// We use the default copy constructor
|
||||
// We use the default operator=()
|
||||
// We use the default destructor
|
||||
|
||||
void clear() { rep.clear(); }
|
||||
void swap(sparse_hash_set& hs) { rep.swap(hs.rep); }
|
||||
|
||||
|
||||
// Functions concerning size
|
||||
size_type size() const { return rep.size(); }
|
||||
size_type max_size() const { return rep.max_size(); }
|
||||
bool empty() const { return rep.empty(); }
|
||||
size_type bucket_count() const { return rep.bucket_count(); }
|
||||
size_type max_bucket_count() const { return rep.max_bucket_count(); }
|
||||
|
||||
// These are tr1 methods. bucket() is the bucket the key is or would be in.
|
||||
size_type bucket_size(size_type i) const { return rep.bucket_size(i); }
|
||||
size_type bucket(const key_type& key) const { return rep.bucket(key); }
|
||||
float load_factor() const {
|
||||
return size() * 1.0f / bucket_count();
|
||||
}
|
||||
float max_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return grow;
|
||||
}
|
||||
void max_load_factor(float new_grow) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(shrink, new_grow);
|
||||
}
|
||||
// These aren't tr1 methods but perhaps ought to be.
|
||||
float min_load_factor() const {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
return shrink;
|
||||
}
|
||||
void min_load_factor(float new_shrink) {
|
||||
float shrink, grow;
|
||||
rep.get_resizing_parameters(&shrink, &grow);
|
||||
rep.set_resizing_parameters(new_shrink, grow);
|
||||
}
|
||||
// Deprecated; use min_load_factor() or max_load_factor() instead.
|
||||
void set_resizing_parameters(float shrink, float grow) {
|
||||
rep.set_resizing_parameters(shrink, grow);
|
||||
}
|
||||
|
||||
void resize(size_type hint) { rep.resize(hint); }
|
||||
void rehash(size_type hint) { resize(hint); } // the tr1 name
|
||||
|
||||
// Lookup routines
|
||||
iterator find(const key_type& key) const { return rep.find(key); }
|
||||
|
||||
size_type count(const key_type& key) const { return rep.count(key); }
|
||||
|
||||
std::pair<iterator, iterator> equal_range(const key_type& key) const {
|
||||
return rep.equal_range(key);
|
||||
}
|
||||
|
||||
|
||||
// Insertion routines
|
||||
std::pair<iterator, bool> insert(const value_type& obj) {
|
||||
std::pair<typename ht::iterator, bool> p = rep.insert(obj);
|
||||
return std::pair<iterator, bool>(p.first, p.second); // const to non-const
|
||||
}
|
||||
template <class InputIterator> void insert(InputIterator f, InputIterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
void insert(const_iterator f, const_iterator l) {
|
||||
rep.insert(f, l);
|
||||
}
|
||||
// Required for std::insert_iterator; the passed-in iterator is ignored.
|
||||
iterator insert(iterator, const value_type& obj) {
|
||||
return insert(obj).first;
|
||||
}
|
||||
|
||||
// Deletion routines
|
||||
// THESE ARE NON-STANDARD! I make you specify an "impossible" key
|
||||
// value to identify deleted buckets. You can change the key as
|
||||
// time goes on, or get rid of it entirely to be insert-only.
|
||||
void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
|
||||
void clear_deleted_key() { rep.clear_deleted_key(); }
|
||||
key_type deleted_key() const { return rep.deleted_key(); }
|
||||
|
||||
// These are standard
|
||||
size_type erase(const key_type& key) { return rep.erase(key); }
|
||||
void erase(iterator it) { rep.erase(it); }
|
||||
void erase(iterator f, iterator l) { rep.erase(f, l); }
|
||||
|
||||
|
||||
// Comparison
|
||||
bool operator==(const sparse_hash_set& hs) const { return rep == hs.rep; }
|
||||
bool operator!=(const sparse_hash_set& hs) const { return rep != hs.rep; }
|
||||
|
||||
|
||||
// I/O -- this is an add-on for writing metainformation to disk
|
||||
//
|
||||
// For maximum flexibility, this does not assume a particular
|
||||
// file type (though it will probably be a FILE *). We just pass
|
||||
// the fp through to rep.
|
||||
|
||||
// If your keys and values are simple enough, you can pass this
|
||||
// serializer to serialize()/unserialize(). "Simple enough" means
|
||||
// value_type is a POD type that contains no pointers. Note,
|
||||
// however, we don't try to normalize endianness.
|
||||
typedef typename ht::NopointerSerializer NopointerSerializer;
|
||||
|
||||
// serializer: a class providing operator()(OUTPUT*, const value_type&)
|
||||
// (writing value_type to OUTPUT). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an ostream*/subclass_of_ostream*, OR a
|
||||
// pointer to a class providing size_t Write(const void*, size_t),
|
||||
// which writes a buffer into a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully written.
|
||||
// Note basic_ostream<not_char> is not currently supported.
|
||||
template <typename ValueSerializer, typename OUTPUT>
|
||||
bool serialize(ValueSerializer serializer, OUTPUT* fp) {
|
||||
return rep.serialize(serializer, fp);
|
||||
}
|
||||
|
||||
// serializer: a functor providing operator()(INPUT*, value_type*)
|
||||
// (reading from INPUT and into value_type). You can specify a
|
||||
// NopointerSerializer object if appropriate (see above).
|
||||
// fp: either a FILE*, OR an istream*/subclass_of_istream*, OR a
|
||||
// pointer to a class providing size_t Read(void*, size_t),
|
||||
// which reads into a buffer from a stream (which fp presumably
|
||||
// owns) and returns the number of bytes successfully read.
|
||||
// Note basic_istream<not_char> is not currently supported.
|
||||
// NOTE: Since value_type is const Key, ValueSerializer
|
||||
// may need to do a const cast in order to fill in the key.
|
||||
// NOTE: if Key is not a POD type, the serializer MUST use
|
||||
// placement-new to initialize its value, rather than a normal
|
||||
// equals-assignment or similar. (The value_type* passed into
|
||||
// the serializer points to garbage memory.)
|
||||
template <typename ValueSerializer, typename INPUT>
|
||||
bool unserialize(ValueSerializer serializer, INPUT* fp) {
|
||||
return rep.unserialize(serializer, fp);
|
||||
}
|
||||
|
||||
// The four methods below are DEPRECATED.
|
||||
// Use serialize() and unserialize() for new code.
|
||||
template <typename OUTPUT>
|
||||
bool write_metadata(OUTPUT *fp) { return rep.write_metadata(fp); }
|
||||
|
||||
template <typename INPUT>
|
||||
bool read_metadata(INPUT *fp) { return rep.read_metadata(fp); }
|
||||
|
||||
template <typename OUTPUT>
|
||||
bool write_nopointer_data(OUTPUT *fp) { return rep.write_nopointer_data(fp); }
|
||||
|
||||
template <typename INPUT>
|
||||
bool read_nopointer_data(INPUT *fp) { return rep.read_nopointer_data(fp); }
|
||||
};
|
||||
|
||||
template <class Val, class HashFcn, class EqualKey, class Alloc>
|
||||
inline void swap(sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs1,
|
||||
sparse_hash_set<Val, HashFcn, EqualKey, Alloc>& hs2) {
|
||||
hs1.swap(hs2);
|
||||
}
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif /* _SPARSE_HASH_SET_H_ */
|
1820
BeefySysLib/third_party/sparsehash/sparsehash/sparsetable
vendored
Normal file
1820
BeefySysLib/third_party/sparsehash/sparsehash/sparsetable
vendored
Normal file
File diff suppressed because it is too large
Load diff
134
BeefySysLib/third_party/sparsehash/sparsehash/template_util.h
vendored
Normal file
134
BeefySysLib/third_party/sparsehash/sparsehash/template_util.h
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2005 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ----
|
||||
//
|
||||
// Template metaprogramming utility functions.
|
||||
//
|
||||
// This code is compiled directly on many platforms, including client
|
||||
// platforms like Windows, Mac, and embedded systems. Before making
|
||||
// any changes here, make sure that you're not breaking any platforms.
|
||||
//
|
||||
//
|
||||
// The names choosen here reflect those used in tr1 and the boost::mpl
|
||||
// library, there are similar operations used in the Loki library as
|
||||
// well. I prefer the boost names for 2 reasons:
|
||||
// 1. I think that portions of the Boost libraries are more likely to
|
||||
// be included in the c++ standard.
|
||||
// 2. It is not impossible that some of the boost libraries will be
|
||||
// included in our own build in the future.
|
||||
// Both of these outcomes means that we may be able to directly replace
|
||||
// some of these with boost equivalents.
|
||||
//
|
||||
#ifndef BASE_TEMPLATE_UTIL_H_
|
||||
#define BASE_TEMPLATE_UTIL_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// Types small_ and big_ are guaranteed such that sizeof(small_) <
|
||||
// sizeof(big_)
|
||||
typedef char small_;
|
||||
|
||||
struct big_ {
|
||||
char dummy[2];
|
||||
};
|
||||
|
||||
// Identity metafunction.
|
||||
template <class T>
|
||||
struct identity_ {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// integral_constant, defined in tr1, is a wrapper for an integer
|
||||
// value. We don't really need this generality; we could get away
|
||||
// with hardcoding the integer type to bool. We use the fully
|
||||
// general integer_constant for compatibility with tr1.
|
||||
|
||||
template<class T, T v>
|
||||
struct integral_constant {
|
||||
static const T value = v;
|
||||
typedef T value_type;
|
||||
typedef integral_constant<T, v> type;
|
||||
};
|
||||
|
||||
template <class T, T v> const T integral_constant<T, v>::value;
|
||||
|
||||
|
||||
// Abbreviations: true_type and false_type are structs that represent boolean
|
||||
// true and false values. Also define the boost::mpl versions of those names,
|
||||
// true_ and false_.
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
typedef true_type true_;
|
||||
typedef false_type false_;
|
||||
|
||||
// if_ is a templatized conditional statement.
|
||||
// if_<cond, A, B> is a compile time evaluation of cond.
|
||||
// if_<>::type contains A if cond is true, B otherwise.
|
||||
template<bool cond, typename A, typename B>
|
||||
struct if_{
|
||||
typedef A type;
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct if_<false, A, B> {
|
||||
typedef B type;
|
||||
};
|
||||
|
||||
|
||||
// type_equals_ is a template type comparator, similar to Loki IsSameType.
|
||||
// type_equals_<A, B>::value is true iff "A" is the same type as "B".
|
||||
//
|
||||
// New code should prefer base::is_same, defined in base/type_traits.h.
|
||||
// It is functionally identical, but is_same is the standard spelling.
|
||||
template<typename A, typename B>
|
||||
struct type_equals_ : public false_ {
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct type_equals_<A, A> : public true_ {
|
||||
};
|
||||
|
||||
// and_ is a template && operator.
|
||||
// and_<A, B>::value evaluates "A::value && B::value".
|
||||
template<typename A, typename B>
|
||||
struct and_ : public integral_constant<bool, (A::value && B::value)> {
|
||||
};
|
||||
|
||||
// or_ is a template || operator.
|
||||
// or_<A, B>::value evaluates "A::value || B::value".
|
||||
template<typename A, typename B>
|
||||
struct or_ : public integral_constant<bool, (A::value || B::value)> {
|
||||
};
|
||||
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // BASE_TEMPLATE_UTIL_H_
|
342
BeefySysLib/third_party/sparsehash/sparsehash/type_traits.h
vendored
Normal file
342
BeefySysLib/third_party/sparsehash/sparsehash/type_traits.h
vendored
Normal file
|
@ -0,0 +1,342 @@
|
|||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ----
|
||||
//
|
||||
// This code is compiled directly on many platforms, including client
|
||||
// platforms like Windows, Mac, and embedded systems. Before making
|
||||
// any changes here, make sure that you're not breaking any platforms.
|
||||
//
|
||||
// Define a small subset of tr1 type traits. The traits we define are:
|
||||
// is_integral
|
||||
// is_floating_point
|
||||
// is_pointer
|
||||
// is_enum
|
||||
// is_reference
|
||||
// is_pod
|
||||
// has_trivial_constructor
|
||||
// has_trivial_copy
|
||||
// has_trivial_assign
|
||||
// has_trivial_destructor
|
||||
// remove_const
|
||||
// remove_volatile
|
||||
// remove_cv
|
||||
// remove_reference
|
||||
// add_reference
|
||||
// remove_pointer
|
||||
// is_same
|
||||
// is_convertible
|
||||
// We can add more type traits as required.
|
||||
|
||||
#ifndef BASE_TYPE_TRAITS_H_
|
||||
#define BASE_TYPE_TRAITS_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <utility> // For pair
|
||||
|
||||
#include <sparsehash/template_util.h> // For true_type and false_type
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
template <class T> struct is_integral;
|
||||
template <class T> struct is_floating_point;
|
||||
template <class T> struct is_pointer;
|
||||
// MSVC can't compile this correctly, and neither can gcc 3.3.5 (at least)
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
// is_enum uses is_convertible, which is not available on MSVC.
|
||||
template <class T> struct is_enum;
|
||||
#endif
|
||||
template <class T> struct is_reference;
|
||||
template <class T> struct is_pod;
|
||||
template <class T> struct has_trivial_constructor;
|
||||
template <class T> struct has_trivial_copy;
|
||||
template <class T> struct has_trivial_assign;
|
||||
template <class T> struct has_trivial_destructor;
|
||||
template <class T> struct remove_const;
|
||||
template <class T> struct remove_volatile;
|
||||
template <class T> struct remove_cv;
|
||||
template <class T> struct remove_reference;
|
||||
template <class T> struct add_reference;
|
||||
template <class T> struct remove_pointer;
|
||||
template <class T, class U> struct is_same;
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
template <class From, class To> struct is_convertible;
|
||||
#endif
|
||||
|
||||
// is_integral is false except for the built-in integer types. A
|
||||
// cv-qualified type is integral if and only if the underlying type is.
|
||||
template <class T> struct is_integral : false_type { };
|
||||
template<> struct is_integral<bool> : true_type { };
|
||||
template<> struct is_integral<char> : true_type { };
|
||||
template<> struct is_integral<unsigned char> : true_type { };
|
||||
template<> struct is_integral<signed char> : true_type { };
|
||||
#if defined(_MSC_VER)
|
||||
// wchar_t is not by default a distinct type from unsigned short in
|
||||
// Microsoft C.
|
||||
// See http://msdn2.microsoft.com/en-us/library/dh8che7s(VS.80).aspx
|
||||
template<> struct is_integral<__wchar_t> : true_type { };
|
||||
#else
|
||||
template<> struct is_integral<wchar_t> : true_type { };
|
||||
#endif
|
||||
template<> struct is_integral<short> : true_type { };
|
||||
template<> struct is_integral<unsigned short> : true_type { };
|
||||
template<> struct is_integral<int> : true_type { };
|
||||
template<> struct is_integral<unsigned int> : true_type { };
|
||||
template<> struct is_integral<long> : true_type { };
|
||||
template<> struct is_integral<unsigned long> : true_type { };
|
||||
#ifdef HAVE_LONG_LONG
|
||||
template<> struct is_integral<long long> : true_type { };
|
||||
template<> struct is_integral<unsigned long long> : true_type { };
|
||||
#endif
|
||||
template <class T> struct is_integral<const T> : is_integral<T> { };
|
||||
template <class T> struct is_integral<volatile T> : is_integral<T> { };
|
||||
template <class T> struct is_integral<const volatile T> : is_integral<T> { };
|
||||
|
||||
// is_floating_point is false except for the built-in floating-point types.
|
||||
// A cv-qualified type is integral if and only if the underlying type is.
|
||||
template <class T> struct is_floating_point : false_type { };
|
||||
template<> struct is_floating_point<float> : true_type { };
|
||||
template<> struct is_floating_point<double> : true_type { };
|
||||
template<> struct is_floating_point<long double> : true_type { };
|
||||
template <class T> struct is_floating_point<const T>
|
||||
: is_floating_point<T> { };
|
||||
template <class T> struct is_floating_point<volatile T>
|
||||
: is_floating_point<T> { };
|
||||
template <class T> struct is_floating_point<const volatile T>
|
||||
: is_floating_point<T> { };
|
||||
|
||||
// is_pointer is false except for pointer types. A cv-qualified type (e.g.
|
||||
// "int* const", as opposed to "int const*") is cv-qualified if and only if
|
||||
// the underlying type is.
|
||||
template <class T> struct is_pointer : false_type { };
|
||||
template <class T> struct is_pointer<T*> : true_type { };
|
||||
template <class T> struct is_pointer<const T> : is_pointer<T> { };
|
||||
template <class T> struct is_pointer<volatile T> : is_pointer<T> { };
|
||||
template <class T> struct is_pointer<const volatile T> : is_pointer<T> { };
|
||||
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <class T> struct is_class_or_union {
|
||||
template <class U> static small_ tester(void (U::*)());
|
||||
template <class U> static big_ tester(...);
|
||||
static const bool value = sizeof(tester<T>(0)) == sizeof(small_);
|
||||
};
|
||||
|
||||
// is_convertible chokes if the first argument is an array. That's why
|
||||
// we use add_reference here.
|
||||
template <bool NotUnum, class T> struct is_enum_impl
|
||||
: is_convertible<typename add_reference<T>::type, int> { };
|
||||
|
||||
template <class T> struct is_enum_impl<true, T> : false_type { };
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Specified by TR1 [4.5.1] primary type categories.
|
||||
|
||||
// Implementation note:
|
||||
//
|
||||
// Each type is either void, integral, floating point, array, pointer,
|
||||
// reference, member object pointer, member function pointer, enum,
|
||||
// union or class. Out of these, only integral, floating point, reference,
|
||||
// class and enum types are potentially convertible to int. Therefore,
|
||||
// if a type is not a reference, integral, floating point or class and
|
||||
// is convertible to int, it's a enum. Adding cv-qualification to a type
|
||||
// does not change whether it's an enum.
|
||||
//
|
||||
// Is-convertible-to-int check is done only if all other checks pass,
|
||||
// because it can't be used with some types (e.g. void or classes with
|
||||
// inaccessible conversion operators).
|
||||
template <class T> struct is_enum
|
||||
: internal::is_enum_impl<
|
||||
is_same<T, void>::value ||
|
||||
is_integral<T>::value ||
|
||||
is_floating_point<T>::value ||
|
||||
is_reference<T>::value ||
|
||||
internal::is_class_or_union<T>::value,
|
||||
T> { };
|
||||
|
||||
template <class T> struct is_enum<const T> : is_enum<T> { };
|
||||
template <class T> struct is_enum<volatile T> : is_enum<T> { };
|
||||
template <class T> struct is_enum<const volatile T> : is_enum<T> { };
|
||||
|
||||
#endif
|
||||
|
||||
// is_reference is false except for reference types.
|
||||
template<typename T> struct is_reference : false_type {};
|
||||
template<typename T> struct is_reference<T&> : true_type {};
|
||||
|
||||
|
||||
// We can't get is_pod right without compiler help, so fail conservatively.
|
||||
// We will assume it's false except for arithmetic types, enumerations,
|
||||
// pointers and cv-qualified versions thereof. Note that std::pair<T,U>
|
||||
// is not a POD even if T and U are PODs.
|
||||
template <class T> struct is_pod
|
||||
: integral_constant<bool, (is_integral<T>::value ||
|
||||
is_floating_point<T>::value ||
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
// is_enum is not available on MSVC.
|
||||
is_enum<T>::value ||
|
||||
#endif
|
||||
is_pointer<T>::value)> { };
|
||||
template <class T> struct is_pod<const T> : is_pod<T> { };
|
||||
template <class T> struct is_pod<volatile T> : is_pod<T> { };
|
||||
template <class T> struct is_pod<const volatile T> : is_pod<T> { };
|
||||
|
||||
|
||||
// We can't get has_trivial_constructor right without compiler help, so
|
||||
// fail conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial
|
||||
// constructors. (3) array of a type with a trivial constructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_constructor : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_constructor<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_constructor<T>::value &&
|
||||
has_trivial_constructor<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_constructor<A[N]>
|
||||
: has_trivial_constructor<A> { };
|
||||
template <class T> struct has_trivial_constructor<const T>
|
||||
: has_trivial_constructor<T> { };
|
||||
|
||||
// We can't get has_trivial_copy right without compiler help, so fail
|
||||
// conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial copy
|
||||
// constructors. (3) array of a type with a trivial copy constructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_copy : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_copy<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_copy<T>::value &&
|
||||
has_trivial_copy<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_copy<A[N]>
|
||||
: has_trivial_copy<A> { };
|
||||
template <class T> struct has_trivial_copy<const T> : has_trivial_copy<T> { };
|
||||
|
||||
// We can't get has_trivial_assign right without compiler help, so fail
|
||||
// conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial copy
|
||||
// constructors. (3) array of a type with a trivial assign constructor.
|
||||
template <class T> struct has_trivial_assign : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_assign<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_assign<T>::value &&
|
||||
has_trivial_assign<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_assign<A[N]>
|
||||
: has_trivial_assign<A> { };
|
||||
|
||||
// We can't get has_trivial_destructor right without compiler help, so
|
||||
// fail conservatively. We will assume it's false except for: (1) types
|
||||
// for which is_pod is true. (2) std::pair of types with trivial
|
||||
// destructors. (3) array of a type with a trivial destructor.
|
||||
// (4) const versions thereof.
|
||||
template <class T> struct has_trivial_destructor : is_pod<T> { };
|
||||
template <class T, class U> struct has_trivial_destructor<std::pair<T, U> >
|
||||
: integral_constant<bool,
|
||||
(has_trivial_destructor<T>::value &&
|
||||
has_trivial_destructor<U>::value)> { };
|
||||
template <class A, int N> struct has_trivial_destructor<A[N]>
|
||||
: has_trivial_destructor<A> { };
|
||||
template <class T> struct has_trivial_destructor<const T>
|
||||
: has_trivial_destructor<T> { };
|
||||
|
||||
// Specified by TR1 [4.7.1]
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<T const> { typedef T type; };
|
||||
template<typename T> struct remove_volatile { typedef T type; };
|
||||
template<typename T> struct remove_volatile<T volatile> { typedef T type; };
|
||||
template<typename T> struct remove_cv {
|
||||
typedef typename remove_const<typename remove_volatile<T>::type>::type type;
|
||||
};
|
||||
|
||||
|
||||
// Specified by TR1 [4.7.2] Reference modifications.
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
|
||||
template <typename T> struct add_reference { typedef T& type; };
|
||||
template <typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
// Specified by TR1 [4.7.4] Pointer modifications.
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* const> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* volatile> { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T* const volatile> {
|
||||
typedef T type; };
|
||||
|
||||
// Specified by TR1 [4.6] Relationships between types
|
||||
template<typename T, typename U> struct is_same : public false_type { };
|
||||
template<typename T> struct is_same<T, T> : public true_type { };
|
||||
|
||||
// Specified by TR1 [4.6] Relationships between types
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
namespace internal {
|
||||
|
||||
// This class is an implementation detail for is_convertible, and you
|
||||
// don't need to know how it works to use is_convertible. For those
|
||||
// who care: we declare two different functions, one whose argument is
|
||||
// of type To and one with a variadic argument list. We give them
|
||||
// return types of different size, so we can use sizeof to trick the
|
||||
// compiler into telling us which function it would have chosen if we
|
||||
// had called it with an argument of type From. See Alexandrescu's
|
||||
// _Modern C++ Design_ for more details on this sort of trick.
|
||||
|
||||
template <typename From, typename To>
|
||||
struct ConvertHelper {
|
||||
static small_ Test(To);
|
||||
static big_ Test(...);
|
||||
static From Create();
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
// Inherits from true_type if From is convertible to To, false_type otherwise.
|
||||
template <typename From, typename To>
|
||||
struct is_convertible
|
||||
: integral_constant<bool,
|
||||
sizeof(internal::ConvertHelper<From, To>::Test(
|
||||
internal::ConvertHelper<From, To>::Create()))
|
||||
== sizeof(small_)> {
|
||||
};
|
||||
#endif
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
// Right now these macros are no-ops, and mostly just document the fact
|
||||
// these types are PODs, for human use. They may be made more contentful
|
||||
// later. The typedef is just to make it legal to put a semicolon after
|
||||
// these macros.
|
||||
#define DECLARE_POD(TypeName) typedef int Dummy_Type_For_DECLARE_POD
|
||||
#define DECLARE_NESTED_POD(TypeName) DECLARE_POD(TypeName)
|
||||
#define PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT(TemplateName) \
|
||||
typedef int Dummy_Type_For_PROPAGATE_POD_FROM_TEMPLATE_ARGUMENT
|
||||
#define ENFORCE_POD(TypeName) typedef int Dummy_Type_For_ENFORCE_POD
|
||||
|
||||
#endif // BASE_TYPE_TRAITS_H_
|
978
BeefySysLib/third_party/sparsehash/sparsetable_unittest.cc
vendored
Normal file
978
BeefySysLib/third_party/sparsehash/sparsetable_unittest.cc
vendored
Normal file
|
@ -0,0 +1,978 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
//
|
||||
// Since sparsetable is templatized, it's important that we test every
|
||||
// function in every class in this file -- not just to see if it
|
||||
// works, but even if it compiles.
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h> // for size_t
|
||||
#include <stdlib.h> // defines unlink() on some windows platforms(?)
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif // for unlink()
|
||||
#include <memory> // for allocator
|
||||
#include <string>
|
||||
#include <sparsehash/sparsetable>
|
||||
using std::string;
|
||||
using std::allocator;
|
||||
using GOOGLE_NAMESPACE::sparsetable;
|
||||
using GOOGLE_NAMESPACE::DEFAULT_SPARSEGROUP_SIZE;
|
||||
|
||||
typedef u_int16_t uint16;
|
||||
string FLAGS_test_tmpdir = "/tmp/";
|
||||
|
||||
// Many sparsetable operations return a size_t. Rather than have to
|
||||
// use PRIuS everywhere, we'll just cast to a "big enough" value.
|
||||
#define UL(x) ( static_cast<unsigned long>(x) )
|
||||
|
||||
|
||||
static char outbuf[10240]; // big enough for these tests
|
||||
static char* out = outbuf; // where to write next
|
||||
#define LEFT (outbuf + sizeof(outbuf) - out)
|
||||
|
||||
#define TEST(cond) out += snprintf(out, LEFT, #cond "? %s\n", \
|
||||
(cond) ? "yes" : "no");
|
||||
|
||||
inline string AsString(int n) {
|
||||
const int N = 64;
|
||||
char buf[N];
|
||||
snprintf(buf, N, "%d", n);
|
||||
return string(buf);
|
||||
}
|
||||
|
||||
// Test sparsetable with a POD type, int.
|
||||
void TestInt() {
|
||||
out += snprintf(out, LEFT, "int test\n");
|
||||
sparsetable<int> x(7), y(70), z;
|
||||
x.set(4, 10);
|
||||
y.set(12, -12);
|
||||
y.set(47, -47);
|
||||
y.set(48, -48);
|
||||
y.set(49, -49);
|
||||
|
||||
const sparsetable<int> constx(x);
|
||||
const sparsetable<int> consty(y);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test the plain iterators
|
||||
|
||||
for ( sparsetable<int>::iterator it = x.begin(); it != x.end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), int(*it));
|
||||
}
|
||||
for ( sparsetable<int>::const_iterator it = x.begin(); it != x.end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(it - x.begin()), *it);
|
||||
}
|
||||
for ( sparsetable<int>::reverse_iterator it = x.rbegin(); it != x.rend(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(x.rend()-1 - it), int(*it));
|
||||
}
|
||||
for ( sparsetable<int>::const_reverse_iterator it = constx.rbegin(); it != constx.rend(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[%lu]: %d\n", UL(constx.rend()-1 - it), *it);
|
||||
}
|
||||
for ( sparsetable<int>::iterator it = z.begin(); it != z.end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "z[%lu]: %d\n", UL(it - z.begin()), int(*it));
|
||||
}
|
||||
|
||||
{ // array version
|
||||
out += snprintf(out, LEFT, "x[3]: %d\n", int(x[3]));
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", int(x[4]));
|
||||
out += snprintf(out, LEFT, "x[5]: %d\n", int(x[5]));
|
||||
}
|
||||
{
|
||||
sparsetable<int>::iterator it; // non-const version
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
|
||||
it = x.begin() + 4; // should point to the non-zero value
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", int(*it));
|
||||
it--;
|
||||
--it;
|
||||
it += 5;
|
||||
it -= 2;
|
||||
it++;
|
||||
++it;
|
||||
it = it - 3;
|
||||
it = 1 + it; // now at 5
|
||||
out += snprintf(out, LEFT, "x[3]: %d\n", int(it[-2]));
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", int(it[-1]));
|
||||
*it = 55;
|
||||
out += snprintf(out, LEFT, "x[5]: %d\n", int(it[0]));
|
||||
out += snprintf(out, LEFT, "x[5]: %d\n", int(*it));
|
||||
int *x6 = &(it[1]);
|
||||
*x6 = 66;
|
||||
out += snprintf(out, LEFT, "x[6]: %d\n", int(*(it + 1)));
|
||||
// Let's test comparitors as well
|
||||
TEST(it == it);
|
||||
TEST(!(it != it));
|
||||
TEST(!(it < it));
|
||||
TEST(!(it > it));
|
||||
TEST(it <= it);
|
||||
TEST(it >= it);
|
||||
|
||||
sparsetable<int>::iterator it_minus_1 = it - 1;
|
||||
TEST(!(it == it_minus_1));
|
||||
TEST(it != it_minus_1);
|
||||
TEST(!(it < it_minus_1));
|
||||
TEST(it > it_minus_1);
|
||||
TEST(!(it <= it_minus_1));
|
||||
TEST(it >= it_minus_1);
|
||||
TEST(!(it_minus_1 == it));
|
||||
TEST(it_minus_1 != it);
|
||||
TEST(it_minus_1 < it);
|
||||
TEST(!(it_minus_1 > it));
|
||||
TEST(it_minus_1 <= it);
|
||||
TEST(!(it_minus_1 >= it));
|
||||
|
||||
sparsetable<int>::iterator it_plus_1 = it + 1;
|
||||
TEST(!(it == it_plus_1));
|
||||
TEST(it != it_plus_1);
|
||||
TEST(it < it_plus_1);
|
||||
TEST(!(it > it_plus_1));
|
||||
TEST(it <= it_plus_1);
|
||||
TEST(!(it >= it_plus_1));
|
||||
TEST(!(it_plus_1 == it));
|
||||
TEST(it_plus_1 != it);
|
||||
TEST(!(it_plus_1 < it));
|
||||
TEST(it_plus_1 > it);
|
||||
TEST(!(it_plus_1 <= it));
|
||||
TEST(it_plus_1 >= it);
|
||||
}
|
||||
{
|
||||
sparsetable<int>::const_iterator it; // const version
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", int(x.begin()[4]));
|
||||
it = x.begin() + 4; // should point to the non-zero value
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", *it);
|
||||
it--;
|
||||
--it;
|
||||
it += 5;
|
||||
it -= 2;
|
||||
it++;
|
||||
++it;
|
||||
it = it - 3;
|
||||
it = 1 + it; // now at 5
|
||||
out += snprintf(out, LEFT, "x[3]: %d\n", it[-2]);
|
||||
out += snprintf(out, LEFT, "x[4]: %d\n", it[-1]);
|
||||
out += snprintf(out, LEFT, "x[5]: %d\n", *it);
|
||||
out += snprintf(out, LEFT, "x[6]: %d\n", *(it + 1));
|
||||
// Let's test comparitors as well
|
||||
TEST(it == it);
|
||||
TEST(!(it != it));
|
||||
TEST(!(it < it));
|
||||
TEST(!(it > it));
|
||||
TEST(it <= it);
|
||||
TEST(it >= it);
|
||||
|
||||
sparsetable<int>::const_iterator it_minus_1 = it - 1;
|
||||
TEST(!(it == it_minus_1));
|
||||
TEST(it != it_minus_1);
|
||||
TEST(!(it < it_minus_1));
|
||||
TEST(it > it_minus_1);
|
||||
TEST(!(it <= it_minus_1));
|
||||
TEST(it >= it_minus_1);
|
||||
TEST(!(it_minus_1 == it));
|
||||
TEST(it_minus_1 != it);
|
||||
TEST(it_minus_1 < it);
|
||||
TEST(!(it_minus_1 > it));
|
||||
TEST(it_minus_1 <= it);
|
||||
TEST(!(it_minus_1 >= it));
|
||||
|
||||
sparsetable<int>::const_iterator it_plus_1 = it + 1;
|
||||
TEST(!(it == it_plus_1));
|
||||
TEST(it != it_plus_1);
|
||||
TEST(it < it_plus_1);
|
||||
TEST(!(it > it_plus_1));
|
||||
TEST(it <= it_plus_1);
|
||||
TEST(!(it >= it_plus_1));
|
||||
TEST(!(it_plus_1 == it));
|
||||
TEST(it_plus_1 != it);
|
||||
TEST(!(it_plus_1 < it));
|
||||
TEST(it_plus_1 > it);
|
||||
TEST(!(it_plus_1 <= it));
|
||||
TEST(it_plus_1 >= it);
|
||||
}
|
||||
|
||||
TEST(x.begin() == x.begin() + 1 - 1);
|
||||
TEST(x.begin() < x.end());
|
||||
TEST(z.begin() < z.end());
|
||||
TEST(z.begin() <= z.end());
|
||||
TEST(z.begin() == z.end());
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test the non-empty iterators
|
||||
|
||||
for ( sparsetable<int>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[??]: %d\n", *it);
|
||||
}
|
||||
for ( sparsetable<int>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
|
||||
}
|
||||
for ( sparsetable<int>::reverse_nonempty_iterator it = y.nonempty_rbegin(); it != y.nonempty_rend(); ++it ) {
|
||||
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
|
||||
}
|
||||
for ( sparsetable<int>::const_reverse_nonempty_iterator it = consty.nonempty_rbegin(); it != consty.nonempty_rend(); ++it ) {
|
||||
out += snprintf(out, LEFT, "y[??]: %d\n", *it);
|
||||
}
|
||||
for ( sparsetable<int>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "z[??]: %d\n", *it);
|
||||
}
|
||||
|
||||
{
|
||||
sparsetable<int>::nonempty_iterator it; // non-const version
|
||||
out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
|
||||
it = x.nonempty_begin();
|
||||
++it; // should be at end
|
||||
--it;
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
|
||||
it--;
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
|
||||
}
|
||||
{
|
||||
sparsetable<int>::const_nonempty_iterator it; // non-const version
|
||||
out += snprintf(out, LEFT, "first non-empty y: %d\n", *y.nonempty_begin());
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *x.nonempty_begin());
|
||||
it = x.nonempty_begin();
|
||||
++it; // should be at end
|
||||
--it;
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
|
||||
it--;
|
||||
out += snprintf(out, LEFT, "first non-empty x: %d\n", *it++);
|
||||
}
|
||||
|
||||
TEST(x.begin() == x.begin() + 1 - 1);
|
||||
TEST(z.begin() != z.end());
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test the non-empty iterators get_pos function
|
||||
|
||||
sparsetable<unsigned int> gp(100);
|
||||
for (int i = 0; i < 100; i += 9) {
|
||||
gp.set(i,i);
|
||||
}
|
||||
|
||||
for (sparsetable<unsigned int>::const_nonempty_iterator
|
||||
it = gp.nonempty_begin(); it != gp.nonempty_end(); ++it) {
|
||||
out += snprintf(out, LEFT,
|
||||
"get_pos() for const nonempty_iterator: %u == %lu\n",
|
||||
*it, UL(gp.get_pos(it)));
|
||||
}
|
||||
|
||||
for (sparsetable<unsigned int>::nonempty_iterator
|
||||
it = gp.nonempty_begin(); it != gp.nonempty_end(); ++it) {
|
||||
out += snprintf(out, LEFT,
|
||||
"get_pos() for nonempty_iterator: %u == %lu\n",
|
||||
*it, UL(gp.get_pos(it)));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test sparsetable functions
|
||||
out += snprintf(out, LEFT, "x has %lu/%lu buckets, "
|
||||
"y %lu/%lu, z %lu/%lu\n",
|
||||
UL(x.num_nonempty()), UL(x.size()),
|
||||
UL(y.num_nonempty()), UL(y.size()),
|
||||
UL(z.num_nonempty()), UL(z.size()));
|
||||
|
||||
y.resize(48); // should get rid of 48 and 49
|
||||
y.resize(70); // 48 and 49 should still be gone
|
||||
out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
|
||||
UL(y.num_nonempty()), UL(y.size()));
|
||||
out += snprintf(out, LEFT, "y[12] = %d, y.get(12) = %d\n", int(y[12]), y.get(12));
|
||||
y.erase(12);
|
||||
out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
|
||||
"y[12] = %d, y.get(12) = %d\n",
|
||||
UL(y.num_nonempty()), UL(y.size()), int(y[12]), y.get(12));
|
||||
|
||||
swap(x, y);
|
||||
|
||||
y.clear();
|
||||
TEST(y == z);
|
||||
|
||||
y.resize(70);
|
||||
for ( int i = 10; i < 40; ++i )
|
||||
y[i] = -i;
|
||||
y.erase(y.begin() + 15, y.begin() + 30);
|
||||
y.erase(y.begin() + 34);
|
||||
y.erase(12);
|
||||
y.resize(38);
|
||||
y.resize(10000);
|
||||
y[9898] = -9898;
|
||||
for ( sparsetable<int>::const_iterator it = y.begin(); it != y.end(); ++it ) {
|
||||
if ( y.test(it) )
|
||||
out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
|
||||
}
|
||||
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
|
||||
|
||||
out += snprintf(out, LEFT, "Starting from y[32]...\n");
|
||||
for ( sparsetable<int>::const_nonempty_iterator it = y.get_iter(32);
|
||||
it != y.nonempty_end(); ++it )
|
||||
out += snprintf(out, LEFT, "y[??] = %d\n", *it);
|
||||
|
||||
out += snprintf(out, LEFT, "From y[32] down...\n");
|
||||
for ( sparsetable<int>::nonempty_iterator it = y.get_iter(32);
|
||||
it != y.nonempty_begin(); )
|
||||
out += snprintf(out, LEFT, "y[??] = %d\n", *--it);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test I/O using deprecated read/write_metadata
|
||||
string filestr = FLAGS_test_tmpdir + "/.sparsetable.test";
|
||||
const char *file = filestr.c_str();
|
||||
FILE *fp = fopen(file, "wb");
|
||||
if ( fp == NULL ) {
|
||||
// maybe we can't write to /tmp/. Try the current directory
|
||||
file = ".sparsetable.test";
|
||||
fp = fopen(file, "wb");
|
||||
}
|
||||
if ( fp == NULL ) {
|
||||
out += snprintf(out, LEFT, "Can't open %s, skipping disk write...\n", file);
|
||||
} else {
|
||||
y.write_metadata(fp); // only write meta-information
|
||||
y.write_nopointer_data(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
fp = fopen(file, "rb");
|
||||
if ( fp == NULL ) {
|
||||
out += snprintf(out, LEFT, "Can't open %s, skipping disk read...\n", file);
|
||||
} else {
|
||||
sparsetable<int> y2;
|
||||
y2.read_metadata(fp);
|
||||
y2.read_nopointer_data(fp);
|
||||
fclose(fp);
|
||||
|
||||
for ( sparsetable<int>::const_iterator it = y2.begin(); it != y2.end(); ++it ) {
|
||||
if ( y2.test(it) )
|
||||
out += snprintf(out, LEFT, "y2[%lu] is %d\n", UL(it - y2.begin()), *it);
|
||||
}
|
||||
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y2.num_nonempty()));
|
||||
}
|
||||
unlink(file);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Also test I/O using serialize()/unserialize()
|
||||
fp = fopen(file, "wb");
|
||||
if ( fp == NULL ) {
|
||||
out += snprintf(out, LEFT, "Can't open %s, skipping disk write...\n", file);
|
||||
} else {
|
||||
y.serialize(sparsetable<int>::NopointerSerializer(), fp);
|
||||
fclose(fp);
|
||||
}
|
||||
fp = fopen(file, "rb");
|
||||
if ( fp == NULL ) {
|
||||
out += snprintf(out, LEFT, "Can't open %s, skipping disk read...\n", file);
|
||||
} else {
|
||||
sparsetable<int> y2;
|
||||
y2.unserialize(sparsetable<int>::NopointerSerializer(), fp);
|
||||
fclose(fp);
|
||||
|
||||
for ( sparsetable<int>::const_iterator it = y2.begin(); it != y2.end(); ++it ) {
|
||||
if ( y2.test(it) )
|
||||
out += snprintf(out, LEFT, "y2[%lu] is %d\n", UL(it - y2.begin()), *it);
|
||||
}
|
||||
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y2.num_nonempty()));
|
||||
}
|
||||
unlink(file);
|
||||
}
|
||||
|
||||
// Test sparsetable with a non-POD type, std::string
|
||||
void TestString() {
|
||||
out += snprintf(out, LEFT, "string test\n");
|
||||
sparsetable<string> x(7), y(70), z;
|
||||
x.set(4, "foo");
|
||||
y.set(12, "orange");
|
||||
y.set(47, "grape");
|
||||
y.set(48, "pear");
|
||||
y.set(49, "apple");
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test the plain iterators
|
||||
|
||||
for ( sparsetable<string>::iterator it = x.begin(); it != x.end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[%lu]: %s\n",
|
||||
UL(it - x.begin()), static_cast<string>(*it).c_str());
|
||||
}
|
||||
for ( sparsetable<string>::iterator it = z.begin(); it != z.end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "z[%lu]: %s\n",
|
||||
UL(it - z.begin()), static_cast<string>(*it).c_str());
|
||||
}
|
||||
|
||||
TEST(x.begin() == x.begin() + 1 - 1);
|
||||
TEST(x.begin() < x.end());
|
||||
TEST(z.begin() < z.end());
|
||||
TEST(z.begin() <= z.end());
|
||||
TEST(z.begin() == z.end());
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test the non-empty iterators
|
||||
for ( sparsetable<string>::nonempty_iterator it = x.nonempty_begin(); it != x.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "x[??]: %s\n", it->c_str());
|
||||
}
|
||||
for ( sparsetable<string>::const_nonempty_iterator it = y.nonempty_begin(); it != y.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "y[??]: %s\n", it->c_str());
|
||||
}
|
||||
for ( sparsetable<string>::nonempty_iterator it = z.nonempty_begin(); it != z.nonempty_end(); ++it ) {
|
||||
out += snprintf(out, LEFT, "z[??]: %s\n", it->c_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Test sparsetable functions
|
||||
out += snprintf(out, LEFT, "x has %lu/%lu buckets, y %lu/%lu, z %lu/%lu\n",
|
||||
UL(x.num_nonempty()), UL(x.size()),
|
||||
UL(y.num_nonempty()), UL(y.size()),
|
||||
UL(z.num_nonempty()), UL(z.size()));
|
||||
|
||||
y.resize(48); // should get rid of 48 and 49
|
||||
y.resize(70); // 48 and 49 should still be gone
|
||||
out += snprintf(out, LEFT, "y shrank and grew: it's now %lu/%lu\n",
|
||||
UL(y.num_nonempty()), UL(y.size()));
|
||||
out += snprintf(out, LEFT, "y[12] = %s, y.get(12) = %s\n",
|
||||
static_cast<string>(y[12]).c_str(), y.get(12).c_str());
|
||||
y.erase(12);
|
||||
out += snprintf(out, LEFT, "y[12] cleared. y now %lu/%lu. "
|
||||
"y[12] = %s, y.get(12) = %s\n",
|
||||
UL(y.num_nonempty()), UL(y.size()),
|
||||
static_cast<string>(y[12]).c_str(),
|
||||
static_cast<string>(y.get(12)).c_str());
|
||||
swap(x, y);
|
||||
|
||||
y.clear();
|
||||
TEST(y == z);
|
||||
|
||||
y.resize(70);
|
||||
for ( int i = 10; i < 40; ++i )
|
||||
y.set(i, AsString(-i));
|
||||
y.erase(y.begin() + 15, y.begin() + 30);
|
||||
y.erase(y.begin() + 34);
|
||||
y.erase(12);
|
||||
y.resize(38);
|
||||
y.resize(10000);
|
||||
y.set(9898, AsString(-9898));
|
||||
for ( sparsetable<string>::const_iterator it = y.begin(); it != y.end(); ++it ) {
|
||||
if ( y.test(it) )
|
||||
out += snprintf(out, LEFT, "y[%lu] is set\n", UL(it - y.begin()));
|
||||
}
|
||||
out += snprintf(out, LEFT, "That's %lu set buckets\n", UL(y.num_nonempty()));
|
||||
|
||||
out += snprintf(out, LEFT, "Starting from y[32]...\n");
|
||||
for ( sparsetable<string>::const_nonempty_iterator it = y.get_iter(32);
|
||||
it != y.nonempty_end(); ++it )
|
||||
out += snprintf(out, LEFT, "y[??] = %s\n", it->c_str());
|
||||
|
||||
out += snprintf(out, LEFT, "From y[32] down...\n");
|
||||
for ( sparsetable<string>::nonempty_iterator it = y.get_iter(32);
|
||||
it != y.nonempty_begin(); )
|
||||
out += snprintf(out, LEFT, "y[??] = %s\n", (*--it).c_str());
|
||||
}
|
||||
|
||||
// An instrumented allocator that keeps track of all calls to
|
||||
// allocate/deallocate/construct/destroy. It stores the number of times
|
||||
// they were called and the values they were called with. Such information is
|
||||
// stored in the following global variables.
|
||||
|
||||
static size_t sum_allocate_bytes;
|
||||
static size_t sum_deallocate_bytes;
|
||||
|
||||
void ResetAllocatorCounters() {
|
||||
sum_allocate_bytes = 0;
|
||||
sum_deallocate_bytes = 0;
|
||||
}
|
||||
|
||||
template <class T> class instrumented_allocator {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef uint16 size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
|
||||
instrumented_allocator() {}
|
||||
instrumented_allocator(const instrumented_allocator&) {}
|
||||
~instrumented_allocator() {}
|
||||
|
||||
pointer address(reference r) const { return &r; }
|
||||
const_pointer address(const_reference r) const { return &r; }
|
||||
|
||||
pointer allocate(size_type n, const_pointer = 0) {
|
||||
sum_allocate_bytes += n * sizeof(value_type);
|
||||
return static_cast<pointer>(malloc(n * sizeof(value_type)));
|
||||
}
|
||||
void deallocate(pointer p, size_type n) {
|
||||
sum_deallocate_bytes += n * sizeof(value_type);
|
||||
free(p);
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return static_cast<size_type>(-1) / sizeof(value_type);
|
||||
}
|
||||
|
||||
void construct(pointer p, const value_type& val) {
|
||||
new(p) value_type(val);
|
||||
}
|
||||
void destroy(pointer p) {
|
||||
p->~value_type();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
explicit instrumented_allocator(const instrumented_allocator<U>&) {}
|
||||
|
||||
template<class U>
|
||||
struct rebind {
|
||||
typedef instrumented_allocator<U> other;
|
||||
};
|
||||
|
||||
private:
|
||||
void operator=(const instrumented_allocator&);
|
||||
};
|
||||
|
||||
template<class T>
|
||||
inline bool operator==(const instrumented_allocator<T>&,
|
||||
const instrumented_allocator<T>&) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline bool operator!=(const instrumented_allocator<T>&,
|
||||
const instrumented_allocator<T>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test sparsetable with instrumented_allocator.
|
||||
void TestAllocator() {
|
||||
out += snprintf(out, LEFT, "allocator test\n");
|
||||
|
||||
ResetAllocatorCounters();
|
||||
|
||||
// POD (int32) with instrumented_allocator.
|
||||
typedef sparsetable<int, DEFAULT_SPARSEGROUP_SIZE,
|
||||
instrumented_allocator<int> > IntSparseTable;
|
||||
|
||||
IntSparseTable* s1 = new IntSparseTable(10000);
|
||||
TEST(sum_allocate_bytes > 0);
|
||||
for (int i = 0; i < 10000; ++i) {
|
||||
s1->set(i, 0);
|
||||
}
|
||||
TEST(sum_allocate_bytes >= 10000 * sizeof(int));
|
||||
ResetAllocatorCounters();
|
||||
delete s1;
|
||||
TEST(sum_deallocate_bytes >= 10000 * sizeof(int));
|
||||
|
||||
IntSparseTable* s2 = new IntSparseTable(1000);
|
||||
IntSparseTable* s3 = new IntSparseTable(1000);
|
||||
|
||||
for (int i = 0; i < 1000; ++i) {
|
||||
s2->set(i, 0);
|
||||
s3->set(i, 0);
|
||||
}
|
||||
TEST(sum_allocate_bytes >= 2000 * sizeof(int));
|
||||
|
||||
ResetAllocatorCounters();
|
||||
s3->clear();
|
||||
TEST(sum_deallocate_bytes >= 1000 * sizeof(int));
|
||||
|
||||
ResetAllocatorCounters();
|
||||
s2->swap(*s3); // s2 is empty after the swap
|
||||
s2->clear();
|
||||
TEST(sum_deallocate_bytes < 1000 * sizeof(int));
|
||||
for (int i = 0; i < s3->size(); ++i) {
|
||||
s3->erase(i);
|
||||
}
|
||||
TEST(sum_deallocate_bytes >= 1000 * sizeof(int));
|
||||
delete s2;
|
||||
delete s3;
|
||||
|
||||
// POD (int) with default allocator.
|
||||
sparsetable<int> x, y;
|
||||
for (int s = 1000; s <= 40000; s += 1000) {
|
||||
x.resize(s);
|
||||
for (int i = 0; i < s; ++i) {
|
||||
x.set(i, i + 1);
|
||||
}
|
||||
y = x;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
y.erase(i);
|
||||
}
|
||||
y.swap(x);
|
||||
}
|
||||
TEST(x.num_nonempty() == 0);
|
||||
out += snprintf(out, LEFT, "y[0]: %d\n", int(y[0]));
|
||||
out += snprintf(out, LEFT, "y[39999]: %d\n", int(y[39999]));
|
||||
y.clear();
|
||||
|
||||
// POD (int) with std allocator.
|
||||
sparsetable<int, DEFAULT_SPARSEGROUP_SIZE, allocator<int> > u, v;
|
||||
for (int s = 1000; s <= 40000; s += 1000) {
|
||||
u.resize(s);
|
||||
for (int i = 0; i < s; ++i) {
|
||||
u.set(i, i + 1);
|
||||
}
|
||||
v = u;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
v.erase(i);
|
||||
}
|
||||
v.swap(u);
|
||||
}
|
||||
TEST(u.num_nonempty() == 0);
|
||||
out += snprintf(out, LEFT, "v[0]: %d\n", int(v[0]));
|
||||
out += snprintf(out, LEFT, "v[39999]: %d\n", int(v[39999]));
|
||||
v.clear();
|
||||
|
||||
// Non-POD (string) with default allocator.
|
||||
sparsetable<string> a, b;
|
||||
for (int s = 1000; s <= 40000; s += 1000) {
|
||||
a.resize(s);
|
||||
for (int i = 0; i < s; ++i) {
|
||||
a.set(i, "aa");
|
||||
}
|
||||
b = a;
|
||||
for (int i = 0; i < s; ++i) {
|
||||
b.erase(i);
|
||||
}
|
||||
b.swap(a);
|
||||
}
|
||||
TEST(a.num_nonempty() == 0);
|
||||
out += snprintf(out, LEFT, "b[0]: %s\n", b.get(0).c_str());
|
||||
out += snprintf(out, LEFT, "b[39999]: %s\n", b.get(39999).c_str());
|
||||
b.clear();
|
||||
}
|
||||
|
||||
// The expected output from all of the above: TestInt(), TestString() and
|
||||
// TestAllocator().
|
||||
static const char g_expected[] = (
|
||||
"int test\n"
|
||||
"x[0]: 0\n"
|
||||
"x[1]: 0\n"
|
||||
"x[2]: 0\n"
|
||||
"x[3]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[5]: 0\n"
|
||||
"x[6]: 0\n"
|
||||
"x[0]: 0\n"
|
||||
"x[1]: 0\n"
|
||||
"x[2]: 0\n"
|
||||
"x[3]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[5]: 0\n"
|
||||
"x[6]: 0\n"
|
||||
"x[6]: 0\n"
|
||||
"x[5]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[3]: 0\n"
|
||||
"x[2]: 0\n"
|
||||
"x[1]: 0\n"
|
||||
"x[0]: 0\n"
|
||||
"x[6]: 0\n"
|
||||
"x[5]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[3]: 0\n"
|
||||
"x[2]: 0\n"
|
||||
"x[1]: 0\n"
|
||||
"x[0]: 0\n"
|
||||
"x[3]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[5]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[4]: 10\n"
|
||||
"x[3]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[5]: 55\n"
|
||||
"x[5]: 55\n"
|
||||
"x[6]: 66\n"
|
||||
"it == it? yes\n"
|
||||
"!(it != it)? yes\n"
|
||||
"!(it < it)? yes\n"
|
||||
"!(it > it)? yes\n"
|
||||
"it <= it? yes\n"
|
||||
"it >= it? yes\n"
|
||||
"!(it == it_minus_1)? yes\n"
|
||||
"it != it_minus_1? yes\n"
|
||||
"!(it < it_minus_1)? yes\n"
|
||||
"it > it_minus_1? yes\n"
|
||||
"!(it <= it_minus_1)? yes\n"
|
||||
"it >= it_minus_1? yes\n"
|
||||
"!(it_minus_1 == it)? yes\n"
|
||||
"it_minus_1 != it? yes\n"
|
||||
"it_minus_1 < it? yes\n"
|
||||
"!(it_minus_1 > it)? yes\n"
|
||||
"it_minus_1 <= it? yes\n"
|
||||
"!(it_minus_1 >= it)? yes\n"
|
||||
"!(it == it_plus_1)? yes\n"
|
||||
"it != it_plus_1? yes\n"
|
||||
"it < it_plus_1? yes\n"
|
||||
"!(it > it_plus_1)? yes\n"
|
||||
"it <= it_plus_1? yes\n"
|
||||
"!(it >= it_plus_1)? yes\n"
|
||||
"!(it_plus_1 == it)? yes\n"
|
||||
"it_plus_1 != it? yes\n"
|
||||
"!(it_plus_1 < it)? yes\n"
|
||||
"it_plus_1 > it? yes\n"
|
||||
"!(it_plus_1 <= it)? yes\n"
|
||||
"it_plus_1 >= it? yes\n"
|
||||
"x[4]: 10\n"
|
||||
"x[4]: 10\n"
|
||||
"x[3]: 0\n"
|
||||
"x[4]: 10\n"
|
||||
"x[5]: 55\n"
|
||||
"x[6]: 66\n"
|
||||
"it == it? yes\n"
|
||||
"!(it != it)? yes\n"
|
||||
"!(it < it)? yes\n"
|
||||
"!(it > it)? yes\n"
|
||||
"it <= it? yes\n"
|
||||
"it >= it? yes\n"
|
||||
"!(it == it_minus_1)? yes\n"
|
||||
"it != it_minus_1? yes\n"
|
||||
"!(it < it_minus_1)? yes\n"
|
||||
"it > it_minus_1? yes\n"
|
||||
"!(it <= it_minus_1)? yes\n"
|
||||
"it >= it_minus_1? yes\n"
|
||||
"!(it_minus_1 == it)? yes\n"
|
||||
"it_minus_1 != it? yes\n"
|
||||
"it_minus_1 < it? yes\n"
|
||||
"!(it_minus_1 > it)? yes\n"
|
||||
"it_minus_1 <= it? yes\n"
|
||||
"!(it_minus_1 >= it)? yes\n"
|
||||
"!(it == it_plus_1)? yes\n"
|
||||
"it != it_plus_1? yes\n"
|
||||
"it < it_plus_1? yes\n"
|
||||
"!(it > it_plus_1)? yes\n"
|
||||
"it <= it_plus_1? yes\n"
|
||||
"!(it >= it_plus_1)? yes\n"
|
||||
"!(it_plus_1 == it)? yes\n"
|
||||
"it_plus_1 != it? yes\n"
|
||||
"!(it_plus_1 < it)? yes\n"
|
||||
"it_plus_1 > it? yes\n"
|
||||
"!(it_plus_1 <= it)? yes\n"
|
||||
"it_plus_1 >= it? yes\n"
|
||||
"x.begin() == x.begin() + 1 - 1? yes\n"
|
||||
"x.begin() < x.end()? yes\n"
|
||||
"z.begin() < z.end()? no\n"
|
||||
"z.begin() <= z.end()? yes\n"
|
||||
"z.begin() == z.end()? yes\n"
|
||||
"x[??]: 10\n"
|
||||
"x[??]: 55\n"
|
||||
"x[??]: 66\n"
|
||||
"y[??]: -12\n"
|
||||
"y[??]: -47\n"
|
||||
"y[??]: -48\n"
|
||||
"y[??]: -49\n"
|
||||
"y[??]: -49\n"
|
||||
"y[??]: -48\n"
|
||||
"y[??]: -47\n"
|
||||
"y[??]: -12\n"
|
||||
"y[??]: -49\n"
|
||||
"y[??]: -48\n"
|
||||
"y[??]: -47\n"
|
||||
"y[??]: -12\n"
|
||||
"first non-empty y: -12\n"
|
||||
"first non-empty x: 10\n"
|
||||
"first non-empty x: 10\n"
|
||||
"first non-empty x: 10\n"
|
||||
"first non-empty y: -12\n"
|
||||
"first non-empty x: 10\n"
|
||||
"first non-empty x: 10\n"
|
||||
"first non-empty x: 10\n"
|
||||
"x.begin() == x.begin() + 1 - 1? yes\n"
|
||||
"z.begin() != z.end()? no\n"
|
||||
"get_pos() for const nonempty_iterator: 0 == 0\n"
|
||||
"get_pos() for const nonempty_iterator: 9 == 9\n"
|
||||
"get_pos() for const nonempty_iterator: 18 == 18\n"
|
||||
"get_pos() for const nonempty_iterator: 27 == 27\n"
|
||||
"get_pos() for const nonempty_iterator: 36 == 36\n"
|
||||
"get_pos() for const nonempty_iterator: 45 == 45\n"
|
||||
"get_pos() for const nonempty_iterator: 54 == 54\n"
|
||||
"get_pos() for const nonempty_iterator: 63 == 63\n"
|
||||
"get_pos() for const nonempty_iterator: 72 == 72\n"
|
||||
"get_pos() for const nonempty_iterator: 81 == 81\n"
|
||||
"get_pos() for const nonempty_iterator: 90 == 90\n"
|
||||
"get_pos() for const nonempty_iterator: 99 == 99\n"
|
||||
"get_pos() for nonempty_iterator: 0 == 0\n"
|
||||
"get_pos() for nonempty_iterator: 9 == 9\n"
|
||||
"get_pos() for nonempty_iterator: 18 == 18\n"
|
||||
"get_pos() for nonempty_iterator: 27 == 27\n"
|
||||
"get_pos() for nonempty_iterator: 36 == 36\n"
|
||||
"get_pos() for nonempty_iterator: 45 == 45\n"
|
||||
"get_pos() for nonempty_iterator: 54 == 54\n"
|
||||
"get_pos() for nonempty_iterator: 63 == 63\n"
|
||||
"get_pos() for nonempty_iterator: 72 == 72\n"
|
||||
"get_pos() for nonempty_iterator: 81 == 81\n"
|
||||
"get_pos() for nonempty_iterator: 90 == 90\n"
|
||||
"get_pos() for nonempty_iterator: 99 == 99\n"
|
||||
"x has 3/7 buckets, y 4/70, z 0/0\n"
|
||||
"y shrank and grew: it's now 2/70\n"
|
||||
"y[12] = -12, y.get(12) = -12\n"
|
||||
"y[12] cleared. y now 1/70. y[12] = 0, y.get(12) = 0\n"
|
||||
"y == z? no\n"
|
||||
"y[10] is set\n"
|
||||
"y[11] is set\n"
|
||||
"y[13] is set\n"
|
||||
"y[14] is set\n"
|
||||
"y[30] is set\n"
|
||||
"y[31] is set\n"
|
||||
"y[32] is set\n"
|
||||
"y[33] is set\n"
|
||||
"y[35] is set\n"
|
||||
"y[36] is set\n"
|
||||
"y[37] is set\n"
|
||||
"y[9898] is set\n"
|
||||
"That's 12 set buckets\n"
|
||||
"Starting from y[32]...\n"
|
||||
"y[??] = -32\n"
|
||||
"y[??] = -33\n"
|
||||
"y[??] = -35\n"
|
||||
"y[??] = -36\n"
|
||||
"y[??] = -37\n"
|
||||
"y[??] = -9898\n"
|
||||
"From y[32] down...\n"
|
||||
"y[??] = -31\n"
|
||||
"y[??] = -30\n"
|
||||
"y[??] = -14\n"
|
||||
"y[??] = -13\n"
|
||||
"y[??] = -11\n"
|
||||
"y[??] = -10\n"
|
||||
"y2[10] is -10\n"
|
||||
"y2[11] is -11\n"
|
||||
"y2[13] is -13\n"
|
||||
"y2[14] is -14\n"
|
||||
"y2[30] is -30\n"
|
||||
"y2[31] is -31\n"
|
||||
"y2[32] is -32\n"
|
||||
"y2[33] is -33\n"
|
||||
"y2[35] is -35\n"
|
||||
"y2[36] is -36\n"
|
||||
"y2[37] is -37\n"
|
||||
"y2[9898] is -9898\n"
|
||||
"That's 12 set buckets\n"
|
||||
"y2[10] is -10\n"
|
||||
"y2[11] is -11\n"
|
||||
"y2[13] is -13\n"
|
||||
"y2[14] is -14\n"
|
||||
"y2[30] is -30\n"
|
||||
"y2[31] is -31\n"
|
||||
"y2[32] is -32\n"
|
||||
"y2[33] is -33\n"
|
||||
"y2[35] is -35\n"
|
||||
"y2[36] is -36\n"
|
||||
"y2[37] is -37\n"
|
||||
"y2[9898] is -9898\n"
|
||||
"That's 12 set buckets\n"
|
||||
"string test\n"
|
||||
"x[0]: \n"
|
||||
"x[1]: \n"
|
||||
"x[2]: \n"
|
||||
"x[3]: \n"
|
||||
"x[4]: foo\n"
|
||||
"x[5]: \n"
|
||||
"x[6]: \n"
|
||||
"x.begin() == x.begin() + 1 - 1? yes\n"
|
||||
"x.begin() < x.end()? yes\n"
|
||||
"z.begin() < z.end()? no\n"
|
||||
"z.begin() <= z.end()? yes\n"
|
||||
"z.begin() == z.end()? yes\n"
|
||||
"x[??]: foo\n"
|
||||
"y[??]: orange\n"
|
||||
"y[??]: grape\n"
|
||||
"y[??]: pear\n"
|
||||
"y[??]: apple\n"
|
||||
"x has 1/7 buckets, y 4/70, z 0/0\n"
|
||||
"y shrank and grew: it's now 2/70\n"
|
||||
"y[12] = orange, y.get(12) = orange\n"
|
||||
"y[12] cleared. y now 1/70. y[12] = , y.get(12) = \n"
|
||||
"y == z? no\n"
|
||||
"y[10] is set\n"
|
||||
"y[11] is set\n"
|
||||
"y[13] is set\n"
|
||||
"y[14] is set\n"
|
||||
"y[30] is set\n"
|
||||
"y[31] is set\n"
|
||||
"y[32] is set\n"
|
||||
"y[33] is set\n"
|
||||
"y[35] is set\n"
|
||||
"y[36] is set\n"
|
||||
"y[37] is set\n"
|
||||
"y[9898] is set\n"
|
||||
"That's 12 set buckets\n"
|
||||
"Starting from y[32]...\n"
|
||||
"y[??] = -32\n"
|
||||
"y[??] = -33\n"
|
||||
"y[??] = -35\n"
|
||||
"y[??] = -36\n"
|
||||
"y[??] = -37\n"
|
||||
"y[??] = -9898\n"
|
||||
"From y[32] down...\n"
|
||||
"y[??] = -31\n"
|
||||
"y[??] = -30\n"
|
||||
"y[??] = -14\n"
|
||||
"y[??] = -13\n"
|
||||
"y[??] = -11\n"
|
||||
"y[??] = -10\n"
|
||||
"allocator test\n"
|
||||
"sum_allocate_bytes > 0? yes\n"
|
||||
"sum_allocate_bytes >= 10000 * sizeof(int)? yes\n"
|
||||
"sum_deallocate_bytes >= 10000 * sizeof(int)? yes\n"
|
||||
"sum_allocate_bytes >= 2000 * sizeof(int)? yes\n"
|
||||
"sum_deallocate_bytes >= 1000 * sizeof(int)? yes\n"
|
||||
"sum_deallocate_bytes < 1000 * sizeof(int)? yes\n"
|
||||
"sum_deallocate_bytes >= 1000 * sizeof(int)? yes\n"
|
||||
"x.num_nonempty() == 0? yes\n"
|
||||
"y[0]: 1\n"
|
||||
"y[39999]: 40000\n"
|
||||
"u.num_nonempty() == 0? yes\n"
|
||||
"v[0]: 1\n"
|
||||
"v[39999]: 40000\n"
|
||||
"a.num_nonempty() == 0? yes\n"
|
||||
"b[0]: aa\n"
|
||||
"b[39999]: aa\n"
|
||||
);
|
||||
|
||||
// defined at bottom of file for ease of maintainence
|
||||
int main(int argc, char **argv) { // though we ignore the args
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
TestInt();
|
||||
TestString();
|
||||
TestAllocator();
|
||||
|
||||
// Finally, check to see if our output (in out) is what it's supposed to be.
|
||||
const size_t r = sizeof(g_expected) - 1;
|
||||
if ( r != static_cast<size_t>(out - outbuf) || // output not the same size
|
||||
memcmp(outbuf, g_expected, r) ) { // or bytes differed
|
||||
fprintf(stderr, "TESTS FAILED\n\nEXPECTED:\n\n%s\n\nACTUAL:\n\n%s\n\n",
|
||||
g_expected, outbuf);
|
||||
return 1;
|
||||
} else {
|
||||
printf("PASS.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
134
BeefySysLib/third_party/sparsehash/template_util_unittest.cc
vendored
Normal file
134
BeefySysLib/third_party/sparsehash/template_util_unittest.cc
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
// Copyright 2005 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ----
|
||||
//
|
||||
// These tests are really compile time tests.
|
||||
// If you try to step through this in a debugger
|
||||
// you will not see any evaluations, merely that
|
||||
// value is assigned true or false sequentially.
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#include <sparsehash/template_util.h>
|
||||
|
||||
#include "testutil.h"
|
||||
|
||||
using namespace GOOGLE_NAMESPACE;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(TemplateUtilTest, TestSize) {
|
||||
EXPECT_GT(sizeof(GOOGLE_NAMESPACE::big_), sizeof(GOOGLE_NAMESPACE::small_));
|
||||
}
|
||||
|
||||
TEST(TemplateUtilTest, TestIntegralConstants) {
|
||||
// test the built-in types.
|
||||
EXPECT_TRUE(true_type::value);
|
||||
EXPECT_FALSE(false_type::value);
|
||||
|
||||
typedef integral_constant<int, 1> one_type;
|
||||
EXPECT_EQ(1, one_type::value);
|
||||
}
|
||||
|
||||
TEST(TemplateUtilTest, TestTemplateIf) {
|
||||
typedef if_<true, true_type, false_type>::type if_true;
|
||||
EXPECT_TRUE(if_true::value);
|
||||
|
||||
typedef if_<false, true_type, false_type>::type if_false;
|
||||
EXPECT_FALSE(if_false::value);
|
||||
}
|
||||
|
||||
TEST(TemplateUtilTest, TestTemplateTypeEquals) {
|
||||
// Check that the TemplateTypeEquals works correctly.
|
||||
bool value = false;
|
||||
|
||||
// Test the same type is true.
|
||||
value = type_equals_<int, int>::value;
|
||||
EXPECT_TRUE(value);
|
||||
|
||||
// Test different types are false.
|
||||
value = type_equals_<float, int>::value;
|
||||
EXPECT_FALSE(value);
|
||||
|
||||
// Test type aliasing.
|
||||
typedef const int foo;
|
||||
value = type_equals_<const foo, const int>::value;
|
||||
EXPECT_TRUE(value);
|
||||
}
|
||||
|
||||
TEST(TemplateUtilTest, TestTemplateAndOr) {
|
||||
// Check that the TemplateTypeEquals works correctly.
|
||||
bool value = false;
|
||||
|
||||
// Yes && Yes == true.
|
||||
value = and_<true_, true_>::value;
|
||||
EXPECT_TRUE(value);
|
||||
// Yes && No == false.
|
||||
value = and_<true_, false_>::value;
|
||||
EXPECT_FALSE(value);
|
||||
// No && Yes == false.
|
||||
value = and_<false_, true_>::value;
|
||||
EXPECT_FALSE(value);
|
||||
// No && No == false.
|
||||
value = and_<false_, false_>::value;
|
||||
EXPECT_FALSE(value);
|
||||
|
||||
// Yes || Yes == true.
|
||||
value = or_<true_, true_>::value;
|
||||
EXPECT_TRUE(value);
|
||||
// Yes || No == true.
|
||||
value = or_<true_, false_>::value;
|
||||
EXPECT_TRUE(value);
|
||||
// No || Yes == true.
|
||||
value = or_<false_, true_>::value;
|
||||
EXPECT_TRUE(value);
|
||||
// No || No == false.
|
||||
value = or_<false_, false_>::value;
|
||||
EXPECT_FALSE(value);
|
||||
}
|
||||
|
||||
TEST(TemplateUtilTest, TestIdentity) {
|
||||
EXPECT_TRUE(
|
||||
(type_equals_<GOOGLE_NAMESPACE::identity_<int>::type, int>::value));
|
||||
EXPECT_TRUE(
|
||||
(type_equals_<GOOGLE_NAMESPACE::identity_<void>::type, void>::value));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(int, char **) {
|
||||
// All the work is done in the static constructors. If they don't
|
||||
// die, the tests have all passed.
|
||||
std::cout << "PASS\n";
|
||||
return 0;
|
||||
}
|
||||
|
266
BeefySysLib/third_party/sparsehash/testutil.h
vendored
Normal file
266
BeefySysLib/third_party/sparsehash/testutil.h
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
// Copyright (c) 2010, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
|
||||
// This macro mimics a unittest framework, but is a bit less flexible
|
||||
// than most. It requires a superclass to derive from, and does all
|
||||
// work in global constructors. The tricky part is implementing
|
||||
// TYPED_TEST.
|
||||
|
||||
#ifndef SPARSEHASH_TEST_UTIL_H_
|
||||
#define SPARSEHASH_TEST_UTIL_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for exit
|
||||
#include <stdexcept> // for length_error
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
namespace testing {
|
||||
|
||||
#define EXPECT_TRUE(cond) do { \
|
||||
if (!(cond)) { \
|
||||
::fputs("Test failed: " #cond "\n", stderr); \
|
||||
::exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define EXPECT_FALSE(a) EXPECT_TRUE(!(a))
|
||||
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b))
|
||||
#define EXPECT_NE(a, b) EXPECT_TRUE((a) != (b))
|
||||
#define EXPECT_LT(a, b) EXPECT_TRUE((a) < (b))
|
||||
#define EXPECT_GT(a, b) EXPECT_TRUE((a) > (b))
|
||||
#define EXPECT_LE(a, b) EXPECT_TRUE((a) <= (b))
|
||||
#define EXPECT_GE(a, b) EXPECT_TRUE((a) >= (b))
|
||||
|
||||
#define EXPECT_DEATH(cmd, expected_error_string) \
|
||||
try { \
|
||||
cmd; \
|
||||
EXPECT_FALSE("did not see expected error: " #expected_error_string); \
|
||||
} catch (const std::length_error&) { \
|
||||
/* Good, the cmd failed. */ \
|
||||
}
|
||||
|
||||
#define TEST(suitename, testname) \
|
||||
class TEST_##suitename##_##testname { \
|
||||
public: \
|
||||
TEST_##suitename##_##testname() { \
|
||||
::fputs("Running " #suitename "." #testname "\n", stderr); \
|
||||
Run(); \
|
||||
} \
|
||||
void Run(); \
|
||||
}; \
|
||||
static TEST_##suitename##_##testname \
|
||||
test_instance_##suitename##_##testname; \
|
||||
void TEST_##suitename##_##testname::Run()
|
||||
|
||||
|
||||
template<typename C1, typename C2, typename C3, typename C4, typename C5,
|
||||
typename C6> struct TypeList6 {
|
||||
typedef C1 type1;
|
||||
typedef C2 type2;
|
||||
typedef C3 type3;
|
||||
typedef C4 type4;
|
||||
typedef C5 type5;
|
||||
typedef C6 type6;
|
||||
};
|
||||
|
||||
// I need to list 18 types here, for code below to compile, though
|
||||
// only the first 6 are ever used.
|
||||
#define TYPED_TEST_CASE_6(classname, typelist) \
|
||||
typedef typelist::type1 classname##_type1; \
|
||||
typedef typelist::type2 classname##_type2; \
|
||||
typedef typelist::type3 classname##_type3; \
|
||||
typedef typelist::type4 classname##_type4; \
|
||||
typedef typelist::type5 classname##_type5; \
|
||||
typedef typelist::type6 classname##_type6; \
|
||||
static const int classname##_numtypes = 6; \
|
||||
typedef typelist::type1 classname##_type7; \
|
||||
typedef typelist::type1 classname##_type8; \
|
||||
typedef typelist::type1 classname##_type9; \
|
||||
typedef typelist::type1 classname##_type10; \
|
||||
typedef typelist::type1 classname##_type11; \
|
||||
typedef typelist::type1 classname##_type12; \
|
||||
typedef typelist::type1 classname##_type13; \
|
||||
typedef typelist::type1 classname##_type14; \
|
||||
typedef typelist::type1 classname##_type15; \
|
||||
typedef typelist::type1 classname##_type16; \
|
||||
typedef typelist::type1 classname##_type17; \
|
||||
typedef typelist::type1 classname##_type18;
|
||||
|
||||
template<typename C1, typename C2, typename C3, typename C4, typename C5,
|
||||
typename C6, typename C7, typename C8, typename C9, typename C10,
|
||||
typename C11, typename C12, typename C13, typename C14, typename C15,
|
||||
typename C16, typename C17, typename C18> struct TypeList18 {
|
||||
typedef C1 type1;
|
||||
typedef C2 type2;
|
||||
typedef C3 type3;
|
||||
typedef C4 type4;
|
||||
typedef C5 type5;
|
||||
typedef C6 type6;
|
||||
typedef C7 type7;
|
||||
typedef C8 type8;
|
||||
typedef C9 type9;
|
||||
typedef C10 type10;
|
||||
typedef C11 type11;
|
||||
typedef C12 type12;
|
||||
typedef C13 type13;
|
||||
typedef C14 type14;
|
||||
typedef C15 type15;
|
||||
typedef C16 type16;
|
||||
typedef C17 type17;
|
||||
typedef C18 type18;
|
||||
};
|
||||
|
||||
#define TYPED_TEST_CASE_18(classname, typelist) \
|
||||
typedef typelist::type1 classname##_type1; \
|
||||
typedef typelist::type2 classname##_type2; \
|
||||
typedef typelist::type3 classname##_type3; \
|
||||
typedef typelist::type4 classname##_type4; \
|
||||
typedef typelist::type5 classname##_type5; \
|
||||
typedef typelist::type6 classname##_type6; \
|
||||
typedef typelist::type7 classname##_type7; \
|
||||
typedef typelist::type8 classname##_type8; \
|
||||
typedef typelist::type9 classname##_type9; \
|
||||
typedef typelist::type10 classname##_type10; \
|
||||
typedef typelist::type11 classname##_type11; \
|
||||
typedef typelist::type12 classname##_type12; \
|
||||
typedef typelist::type13 classname##_type13; \
|
||||
typedef typelist::type14 classname##_type14; \
|
||||
typedef typelist::type15 classname##_type15; \
|
||||
typedef typelist::type16 classname##_type16; \
|
||||
typedef typelist::type17 classname##_type17; \
|
||||
typedef typelist::type18 classname##_type18; \
|
||||
static const int classname##_numtypes = 18;
|
||||
|
||||
#define TYPED_TEST(superclass, testname) \
|
||||
template<typename TypeParam> \
|
||||
class TEST_onetype_##superclass##_##testname : \
|
||||
public superclass<TypeParam> { \
|
||||
public: \
|
||||
TEST_onetype_##superclass##_##testname() { \
|
||||
Run(); \
|
||||
} \
|
||||
private: \
|
||||
void Run(); \
|
||||
}; \
|
||||
class TEST_typed_##superclass##_##testname { \
|
||||
public: \
|
||||
explicit TEST_typed_##superclass##_##testname() { \
|
||||
if (superclass##_numtypes >= 1) { \
|
||||
::fputs("Running " #superclass "." #testname ".1\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type1> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 2) { \
|
||||
::fputs("Running " #superclass "." #testname ".2\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type2> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 3) { \
|
||||
::fputs("Running " #superclass "." #testname ".3\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type3> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 4) { \
|
||||
::fputs("Running " #superclass "." #testname ".4\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type4> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 5) { \
|
||||
::fputs("Running " #superclass "." #testname ".5\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type5> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 6) { \
|
||||
::fputs("Running " #superclass "." #testname ".6\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type6> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 7) { \
|
||||
::fputs("Running " #superclass "." #testname ".7\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type7> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 8) { \
|
||||
::fputs("Running " #superclass "." #testname ".8\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type8> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 9) { \
|
||||
::fputs("Running " #superclass "." #testname ".9\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type9> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 10) { \
|
||||
::fputs("Running " #superclass "." #testname ".10\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type10> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 11) { \
|
||||
::fputs("Running " #superclass "." #testname ".11\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type11> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 12) { \
|
||||
::fputs("Running " #superclass "." #testname ".12\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type12> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 13) { \
|
||||
::fputs("Running " #superclass "." #testname ".13\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type13> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 14) { \
|
||||
::fputs("Running " #superclass "." #testname ".14\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type14> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 15) { \
|
||||
::fputs("Running " #superclass "." #testname ".15\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type15> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 16) { \
|
||||
::fputs("Running " #superclass "." #testname ".16\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type16> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 17) { \
|
||||
::fputs("Running " #superclass "." #testname ".17\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type17> t; \
|
||||
} \
|
||||
if (superclass##_numtypes >= 18) { \
|
||||
::fputs("Running " #superclass "." #testname ".18\n", stderr); \
|
||||
TEST_onetype_##superclass##_##testname<superclass##_type18> t; \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
static TEST_typed_##superclass##_##testname \
|
||||
test_instance_typed_##superclass##_##testname; \
|
||||
template<class TypeParam> \
|
||||
void TEST_onetype_##superclass##_##testname<TypeParam>::Run()
|
||||
|
||||
// This is a dummy class just to make converting from internal-google
|
||||
// to opensourcing easier.
|
||||
class Test { };
|
||||
|
||||
} // namespace testing
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
#endif // SPARSEHASH_TEST_UTIL_H_
|
729
BeefySysLib/third_party/sparsehash/time_hash_map.cc
vendored
Normal file
729
BeefySysLib/third_party/sparsehash/time_hash_map.cc
vendored
Normal file
|
@ -0,0 +1,729 @@
|
|||
// Copyright (c) 2005, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ---
|
||||
// Authors: Sanjay Ghemawat and Craig Silverstein
|
||||
|
||||
// Time various hash map implementations
|
||||
//
|
||||
// Below, times are per-call. "Memory use" is "bytes in use by
|
||||
// application" as reported by tcmalloc, compared before and after the
|
||||
// function call. This does not really report fragmentation, which is
|
||||
// not bad for the sparse* routines but bad for the dense* ones.
|
||||
//
|
||||
// The tests generally yield best-case performance because the
|
||||
// code uses sequential keys; on the other hand, "map_fetch_random" does
|
||||
// lookups in a pseudorandom order. Also, "stresshashfunction" is
|
||||
// a stress test of sorts. It uses keys from an arithmetic sequence, which,
|
||||
// if combined with a quick-and-dirty hash function, will yield worse
|
||||
// performance than the otherwise similar "map_predict/grow."
|
||||
//
|
||||
// Consider doing the following to get good numbers:
|
||||
//
|
||||
// 1. Run the tests on a machine with no X service. Make sure no other
|
||||
// processes are running.
|
||||
// 2. Minimize compiled-code differences. Compare results from the same
|
||||
// binary, if possible, instead of comparing results from two different
|
||||
// binaries.
|
||||
//
|
||||
// See PERFORMANCE for the output of one example run.
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif // for uintptr_t
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
extern "C" {
|
||||
#include <time.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
# include <sys/utsname.h>
|
||||
#endif // for uname()
|
||||
}
|
||||
|
||||
// The functions that we call on each map, that differ for different types.
|
||||
// By default each is a noop, but we redefine them for types that need them.
|
||||
|
||||
#include <map>
|
||||
#include HASH_MAP_H
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <sparsehash/type_traits.h>
|
||||
#include <sparsehash/dense_hash_map>
|
||||
#include <sparsehash/sparse_hash_map>
|
||||
|
||||
using std::map;
|
||||
using std::swap;
|
||||
using std::vector;
|
||||
using GOOGLE_NAMESPACE::dense_hash_map;
|
||||
using GOOGLE_NAMESPACE::sparse_hash_map;
|
||||
|
||||
static bool FLAGS_test_sparse_hash_map = true;
|
||||
static bool FLAGS_test_dense_hash_map = true;
|
||||
static bool FLAGS_test_hash_map = true;
|
||||
static bool FLAGS_test_map = true;
|
||||
|
||||
static bool FLAGS_test_4_bytes = true;
|
||||
static bool FLAGS_test_8_bytes = true;
|
||||
static bool FLAGS_test_16_bytes = true;
|
||||
static bool FLAGS_test_256_bytes = true;
|
||||
|
||||
#if defined(HAVE_UNORDERED_MAP)
|
||||
using HASH_NAMESPACE::unordered_map;
|
||||
#elif defined(HAVE_HASH_MAP) || defined(_MSC_VER)
|
||||
using HASH_NAMESPACE::hash_map;
|
||||
#endif
|
||||
|
||||
static const int kDefaultIters = 10000000;
|
||||
|
||||
// A version of each of the hashtable classes we test, that has been
|
||||
// augumented to provide a common interface. For instance, the
|
||||
// sparse_hash_map and dense_hash_map versions set empty-key and
|
||||
// deleted-key (we can do this because all our tests use int-like
|
||||
// keys), so the users don't have to. The hash_map version adds
|
||||
// resize(), so users can just call resize() for all tests without
|
||||
// worrying about whether the map-type supports it or not.
|
||||
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseSparseHashMap : public sparse_hash_map<K,V,H> {
|
||||
public:
|
||||
EasyUseSparseHashMap() {
|
||||
this->set_deleted_key(-1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseDenseHashMap : public dense_hash_map<K,V,H> {
|
||||
public:
|
||||
EasyUseDenseHashMap() {
|
||||
this->set_empty_key(-1);
|
||||
this->set_deleted_key(-2);
|
||||
}
|
||||
};
|
||||
|
||||
// For pointers, we only set the empty key.
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseSparseHashMap<K*, V, H> : public sparse_hash_map<K*,V,H> {
|
||||
public:
|
||||
EasyUseSparseHashMap() { }
|
||||
};
|
||||
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseDenseHashMap<K*, V, H> : public dense_hash_map<K*,V,H> {
|
||||
public:
|
||||
EasyUseDenseHashMap() {
|
||||
this->set_empty_key((K*)(~0));
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(HAVE_UNORDERED_MAP)
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseHashMap : public unordered_map<K,V,H> {
|
||||
public:
|
||||
// resize() is called rehash() in tr1
|
||||
void resize(size_t r) { this->rehash(r); }
|
||||
};
|
||||
#elif defined(_MSC_VER)
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseHashMap : public hash_map<K,V,H> {
|
||||
public:
|
||||
void resize(size_t r) { }
|
||||
};
|
||||
#elif defined(HAVE_HASH_MAP)
|
||||
template<typename K, typename V, typename H>
|
||||
class EasyUseHashMap : public hash_map<K,V,H> {
|
||||
public:
|
||||
// Don't need to do anything: hash_map is already easy to use!
|
||||
};
|
||||
#endif
|
||||
|
||||
template<typename K, typename V>
|
||||
class EasyUseMap : public map<K,V> {
|
||||
public:
|
||||
void resize(size_t) { } // map<> doesn't support resize
|
||||
};
|
||||
|
||||
|
||||
// Returns the number of hashes that have been done since the last
|
||||
// call to NumHashesSinceLastCall(). This is shared across all
|
||||
// HashObject instances, which isn't super-OO, but avoids two issues:
|
||||
// (1) making HashObject bigger than it ought to be (this is very
|
||||
// important for our testing), and (2) having to pass around
|
||||
// HashObject objects everywhere, which is annoying.
|
||||
static int g_num_hashes;
|
||||
static int g_num_copies;
|
||||
|
||||
int NumHashesSinceLastCall() {
|
||||
int retval = g_num_hashes;
|
||||
g_num_hashes = 0;
|
||||
return retval;
|
||||
}
|
||||
int NumCopiesSinceLastCall() {
|
||||
int retval = g_num_copies;
|
||||
g_num_copies = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the objects we hash. Size is the size of the object
|
||||
* (must be > sizeof(int). Hashsize is how many of these bytes we
|
||||
* use when hashing (must be > sizeof(int) and < Size).
|
||||
*/
|
||||
template<int Size, int Hashsize> class HashObject {
|
||||
public:
|
||||
typedef HashObject<Size, Hashsize> class_type;
|
||||
HashObject() {}
|
||||
HashObject(int i) : i_(i) {
|
||||
memset(buffer_, i & 255, sizeof(buffer_)); // a "random" char
|
||||
}
|
||||
HashObject(const HashObject& that) {
|
||||
operator=(that);
|
||||
}
|
||||
void operator=(const HashObject& that) {
|
||||
g_num_copies++;
|
||||
this->i_ = that.i_;
|
||||
memcpy(this->buffer_, that.buffer_, sizeof(this->buffer_));
|
||||
}
|
||||
|
||||
size_t Hash() const {
|
||||
g_num_hashes++;
|
||||
int hashval = i_;
|
||||
for (size_t i = 0; i < Hashsize - sizeof(i_); ++i) {
|
||||
hashval += buffer_[i];
|
||||
}
|
||||
return SPARSEHASH_HASH<int>()(hashval);
|
||||
}
|
||||
|
||||
bool operator==(const class_type& that) const { return this->i_ == that.i_; }
|
||||
bool operator< (const class_type& that) const { return this->i_ < that.i_; }
|
||||
bool operator<=(const class_type& that) const { return this->i_ <= that.i_; }
|
||||
|
||||
private:
|
||||
int i_; // the key used for hashing
|
||||
char buffer_[Size - sizeof(int)];
|
||||
};
|
||||
|
||||
// A specialization for the case sizeof(buffer_) == 0
|
||||
template<> class HashObject<sizeof(int), sizeof(int)> {
|
||||
public:
|
||||
typedef HashObject<sizeof(int), sizeof(int)> class_type;
|
||||
HashObject() {}
|
||||
HashObject(int i) : i_(i) {}
|
||||
HashObject(const HashObject& that) {
|
||||
operator=(that);
|
||||
}
|
||||
void operator=(const HashObject& that) {
|
||||
g_num_copies++;
|
||||
this->i_ = that.i_;
|
||||
}
|
||||
|
||||
size_t Hash() const {
|
||||
g_num_hashes++;
|
||||
return SPARSEHASH_HASH<int>()(i_);
|
||||
}
|
||||
|
||||
bool operator==(const class_type& that) const { return this->i_ == that.i_; }
|
||||
bool operator< (const class_type& that) const { return this->i_ < that.i_; }
|
||||
bool operator<=(const class_type& that) const { return this->i_ <= that.i_; }
|
||||
|
||||
private:
|
||||
int i_; // the key used for hashing
|
||||
};
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
|
||||
// Let the hashtable implementations know it can use an optimized memcpy,
|
||||
// because the compiler defines both the destructor and copy constructor.
|
||||
|
||||
template<int Size, int Hashsize>
|
||||
struct has_trivial_copy< HashObject<Size, Hashsize> > : true_type { };
|
||||
|
||||
template<int Size, int Hashsize>
|
||||
struct has_trivial_destructor< HashObject<Size, Hashsize> > : true_type { };
|
||||
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
class HashFn {
|
||||
public:
|
||||
template<int Size, int Hashsize>
|
||||
size_t operator()(const HashObject<Size,Hashsize>& obj) const {
|
||||
return obj.Hash();
|
||||
}
|
||||
// Do the identity hash for pointers.
|
||||
template<int Size, int Hashsize>
|
||||
size_t operator()(const HashObject<Size,Hashsize>* obj) const {
|
||||
return reinterpret_cast<uintptr_t>(obj);
|
||||
}
|
||||
|
||||
// Less operator for MSVC's hash containers.
|
||||
template<int Size, int Hashsize>
|
||||
bool operator()(const HashObject<Size,Hashsize>& a,
|
||||
const HashObject<Size,Hashsize>& b) const {
|
||||
return a < b;
|
||||
}
|
||||
template<int Size, int Hashsize>
|
||||
bool operator()(const HashObject<Size,Hashsize>* a,
|
||||
const HashObject<Size,Hashsize>* b) const {
|
||||
return a < b;
|
||||
}
|
||||
// These two public members are required by msvc. 4 and 8 are defaults.
|
||||
static const size_t bucket_size = 4;
|
||||
static const size_t min_buckets = 8;
|
||||
};
|
||||
|
||||
/*
|
||||
* Measure resource usage.
|
||||
*/
|
||||
|
||||
class Rusage {
|
||||
public:
|
||||
/* Start collecting usage */
|
||||
Rusage() { Reset(); }
|
||||
|
||||
/* Reset collection */
|
||||
void Reset();
|
||||
|
||||
/* Show usage, in seconds */
|
||||
double UserTime();
|
||||
|
||||
private:
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
struct rusage start;
|
||||
#elif defined HAVE_WINDOWS_H
|
||||
long long int start;
|
||||
#else
|
||||
time_t start_time_t;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline void Rusage::Reset() {
|
||||
g_num_copies = 0;
|
||||
g_num_hashes = 0;
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
getrusage(RUSAGE_SELF, &start);
|
||||
#elif defined HAVE_WINDOWS_H
|
||||
start = GetTickCount();
|
||||
#else
|
||||
time(&start_time_t);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline double Rusage::UserTime() {
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
struct rusage u;
|
||||
|
||||
getrusage(RUSAGE_SELF, &u);
|
||||
|
||||
struct timeval result;
|
||||
result.tv_sec = u.ru_utime.tv_sec - start.ru_utime.tv_sec;
|
||||
result.tv_usec = u.ru_utime.tv_usec - start.ru_utime.tv_usec;
|
||||
|
||||
return double(result.tv_sec) + double(result.tv_usec) / 1000000.0;
|
||||
#elif defined HAVE_WINDOWS_H
|
||||
return double(GetTickCount() - start) / 1000.0;
|
||||
#else
|
||||
time_t now;
|
||||
time(&now);
|
||||
return now - start_time_t;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void print_uname() {
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
struct utsname u;
|
||||
if (uname(&u) == 0) {
|
||||
printf("%s %s %s %s %s\n",
|
||||
u.sysname, u.nodename, u.release, u.version, u.machine);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Generate stamp for this run
|
||||
static void stamp_run(int iters) {
|
||||
time_t now = time(0);
|
||||
printf("======\n");
|
||||
fflush(stdout);
|
||||
print_uname();
|
||||
printf("Average over %d iterations\n", iters);
|
||||
fflush(stdout);
|
||||
// don't need asctime_r/gmtime_r: we're not threaded
|
||||
printf("Current time (GMT): %s", asctime(gmtime(&now)));
|
||||
}
|
||||
|
||||
// This depends on the malloc implementation for exactly what it does
|
||||
// -- and thus requires work after the fact to make sense of the
|
||||
// numbers -- and also is likely thrown off by the memory management
|
||||
// STL tries to do on its own.
|
||||
|
||||
#ifdef HAVE_GOOGLE_MALLOC_EXTENSION_H
|
||||
#include <google/malloc_extension.h>
|
||||
|
||||
static size_t CurrentMemoryUsage() {
|
||||
size_t result;
|
||||
if (MallocExtension::instance()->GetNumericProperty(
|
||||
"generic.current_allocated_bytes",
|
||||
&result)) {
|
||||
return result;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* not HAVE_GOOGLE_MALLOC_EXTENSION_H */
|
||||
static size_t CurrentMemoryUsage() { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
static void report(char const* title, double t,
|
||||
int iters,
|
||||
size_t start_memory, size_t end_memory) {
|
||||
// Construct heap growth report text if applicable
|
||||
char heap[100] = "";
|
||||
if (end_memory > start_memory) {
|
||||
snprintf(heap, sizeof(heap), "%7.1f MB",
|
||||
(end_memory - start_memory) / 1048576.0);
|
||||
}
|
||||
|
||||
printf("%-20s %6.1f ns (%8d hashes, %8d copies)%s\n",
|
||||
title, (t * 1000000000.0 / iters),
|
||||
NumHashesSinceLastCall(), NumCopiesSinceLastCall(),
|
||||
heap);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_grow(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
|
||||
const size_t start = CurrentMemoryUsage();
|
||||
t.Reset();
|
||||
for (int i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
const size_t finish = CurrentMemoryUsage();
|
||||
report("map_grow", ut, iters, start, finish);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_grow_predicted(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
|
||||
const size_t start = CurrentMemoryUsage();
|
||||
set.resize(iters);
|
||||
t.Reset();
|
||||
for (int i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
const size_t finish = CurrentMemoryUsage();
|
||||
report("map_predict/grow", ut, iters, start, finish);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_replace(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
|
||||
t.Reset();
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
|
||||
report("map_replace", ut, iters, 0, 0);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_fetch(int iters, const vector<int>& indices,
|
||||
char const* title) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
t.Reset();
|
||||
for (i = 0; i < iters; i++) {
|
||||
r ^= static_cast<int>(set.find(indices[i]) != set.end());
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
|
||||
srand(r); // keep compiler from optimizing away r (we never call rand())
|
||||
report(title, ut, iters, 0, 0);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_fetch_sequential(int iters) {
|
||||
vector<int> v(iters);
|
||||
for (int i = 0; i < iters; i++) {
|
||||
v[i] = i;
|
||||
}
|
||||
time_map_fetch<MapType>(iters, v, "map_fetch_sequential");
|
||||
}
|
||||
|
||||
// Apply a pseudorandom permutation to the given vector.
|
||||
static void shuffle(vector<int>* v) {
|
||||
srand(9);
|
||||
for (int n = v->size(); n >= 2; n--) {
|
||||
swap((*v)[n - 1], (*v)[static_cast<unsigned>(rand()) % n]);
|
||||
}
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_fetch_random(int iters) {
|
||||
vector<int> v(iters);
|
||||
for (int i = 0; i < iters; i++) {
|
||||
v[i] = i;
|
||||
}
|
||||
shuffle(&v);
|
||||
time_map_fetch<MapType>(iters, v, "map_fetch_random");
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_fetch_empty(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
r = 1;
|
||||
t.Reset();
|
||||
for (i = 0; i < iters; i++) {
|
||||
r ^= static_cast<int>(set.find(i) != set.end());
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
|
||||
srand(r); // keep compiler from optimizing away r (we never call rand())
|
||||
report("map_fetch_empty", ut, iters, 0, 0);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_remove(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
|
||||
t.Reset();
|
||||
for (i = 0; i < iters; i++) {
|
||||
set.erase(i);
|
||||
}
|
||||
double ut = t.UserTime();
|
||||
|
||||
report("map_remove", ut, iters, 0, 0);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_toggle(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int i;
|
||||
|
||||
const size_t start = CurrentMemoryUsage();
|
||||
t.Reset();
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
set.erase(i);
|
||||
}
|
||||
|
||||
double ut = t.UserTime();
|
||||
const size_t finish = CurrentMemoryUsage();
|
||||
|
||||
report("map_toggle", ut, iters, start, finish);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void time_map_iterate(int iters) {
|
||||
MapType set;
|
||||
Rusage t;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < iters; i++) {
|
||||
set[i] = i+1;
|
||||
}
|
||||
|
||||
r = 1;
|
||||
t.Reset();
|
||||
for (typename MapType::const_iterator it = set.begin(), it_end = set.end();
|
||||
it != it_end;
|
||||
++it) {
|
||||
r ^= it->second;
|
||||
}
|
||||
|
||||
double ut = t.UserTime();
|
||||
|
||||
srand(r); // keep compiler from optimizing away r (we never call rand())
|
||||
report("map_iterate", ut, iters, 0, 0);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void stresshashfunction(int desired_insertions,
|
||||
int map_size,
|
||||
int stride) {
|
||||
Rusage t;
|
||||
int num_insertions = 0;
|
||||
// One measurement of user time (in seconds) is done for each iteration of
|
||||
// the outer loop. The times are summed.
|
||||
double total_seconds = 0;
|
||||
const int k = desired_insertions / map_size;
|
||||
MapType set;
|
||||
for (int o = 0; o < k; o++) {
|
||||
set.clear();
|
||||
set.resize(map_size);
|
||||
t.Reset();
|
||||
const int maxint = (1ull << (sizeof(int) * 8 - 1)) - 1;
|
||||
// Use n arithmetic sequences. Using just one may lead to overflow
|
||||
// if stride * map_size > maxint. Compute n by requiring
|
||||
// stride * map_size/n < maxint, i.e., map_size/(maxint/stride) < n
|
||||
char* key; // something we can do math on
|
||||
const int n = map_size / (maxint / stride) + 1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
key = NULL;
|
||||
key += i;
|
||||
for (int j = 0; j < map_size/n; j++) {
|
||||
key += stride;
|
||||
set[reinterpret_cast<typename MapType::key_type>(key)]
|
||||
= ++num_insertions;
|
||||
}
|
||||
}
|
||||
total_seconds += t.UserTime();
|
||||
}
|
||||
printf("stresshashfunction map_size=%d stride=%d: %.1fns/insertion\n",
|
||||
map_size, stride, total_seconds * 1e9 / num_insertions);
|
||||
}
|
||||
|
||||
template<class MapType>
|
||||
static void stresshashfunction(int num_inserts) {
|
||||
static const int kMapSizes[] = {256, 1024};
|
||||
for (unsigned i = 0; i < sizeof(kMapSizes) / sizeof(kMapSizes[0]); i++) {
|
||||
const int map_size = kMapSizes[i];
|
||||
for (int stride = 1; stride <= map_size; stride *= map_size) {
|
||||
stresshashfunction<MapType>(num_inserts, map_size, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class MapType, class StressMapType>
|
||||
static void measure_map(const char* label, int obj_size, int iters,
|
||||
bool stress_hash_function) {
|
||||
printf("\n%s (%d byte objects, %d iterations):\n", label, obj_size, iters);
|
||||
if (1) time_map_grow<MapType>(iters);
|
||||
if (1) time_map_grow_predicted<MapType>(iters);
|
||||
if (1) time_map_replace<MapType>(iters);
|
||||
if (1) time_map_fetch_random<MapType>(iters);
|
||||
if (1) time_map_fetch_sequential<MapType>(iters);
|
||||
if (1) time_map_fetch_empty<MapType>(iters);
|
||||
if (1) time_map_remove<MapType>(iters);
|
||||
if (1) time_map_toggle<MapType>(iters);
|
||||
if (1) time_map_iterate<MapType>(iters);
|
||||
// This last test is useful only if the map type uses hashing.
|
||||
// And it's slow, so use fewer iterations.
|
||||
if (stress_hash_function) {
|
||||
// Blank line in the output makes clear that what follows isn't part of the
|
||||
// table of results that we just printed.
|
||||
puts("");
|
||||
stresshashfunction<StressMapType>(iters / 4);
|
||||
}
|
||||
}
|
||||
|
||||
template<class ObjType>
|
||||
static void test_all_maps(int obj_size, int iters) {
|
||||
const bool stress_hash_function = obj_size <= 8;
|
||||
|
||||
if (FLAGS_test_sparse_hash_map)
|
||||
measure_map< EasyUseSparseHashMap<ObjType, int, HashFn>,
|
||||
EasyUseSparseHashMap<ObjType*, int, HashFn> >(
|
||||
"SPARSE_HASH_MAP", obj_size, iters, stress_hash_function);
|
||||
|
||||
if (FLAGS_test_dense_hash_map)
|
||||
measure_map< EasyUseDenseHashMap<ObjType, int, HashFn>,
|
||||
EasyUseDenseHashMap<ObjType*, int, HashFn> >(
|
||||
"DENSE_HASH_MAP", obj_size, iters, stress_hash_function);
|
||||
|
||||
if (FLAGS_test_hash_map)
|
||||
measure_map< EasyUseHashMap<ObjType, int, HashFn>,
|
||||
EasyUseHashMap<ObjType*, int, HashFn> >(
|
||||
"STANDARD HASH_MAP", obj_size, iters, stress_hash_function);
|
||||
|
||||
if (FLAGS_test_map)
|
||||
measure_map< EasyUseMap<ObjType, int>,
|
||||
EasyUseMap<ObjType*, int> >(
|
||||
"STANDARD MAP", obj_size, iters, false);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
int iters = kDefaultIters;
|
||||
if (argc > 1) { // first arg is # of iterations
|
||||
iters = atoi(argv[1]);
|
||||
}
|
||||
|
||||
stamp_run(iters);
|
||||
|
||||
#ifndef HAVE_SYS_RESOURCE_H
|
||||
printf("\n*** WARNING ***: sys/resources.h was not found, so all times\n"
|
||||
" reported are wall-clock time, not user time\n");
|
||||
#endif
|
||||
|
||||
// It would be nice to set these at run-time, but by setting them at
|
||||
// compile-time, we allow optimizations that make it as fast to use
|
||||
// a HashObject as it would be to use just a straight int/char
|
||||
// buffer. To keep memory use similar, we normalize the number of
|
||||
// iterations based on size.
|
||||
if (FLAGS_test_4_bytes) test_all_maps< HashObject<4,4> >(4, iters/1);
|
||||
if (FLAGS_test_8_bytes) test_all_maps< HashObject<8,8> >(8, iters/2);
|
||||
if (FLAGS_test_16_bytes) test_all_maps< HashObject<16,16> >(16, iters/4);
|
||||
if (FLAGS_test_256_bytes) test_all_maps< HashObject<256,32> >(256, iters/32);
|
||||
|
||||
return 0;
|
||||
}
|
636
BeefySysLib/third_party/sparsehash/type_traits_unittest.cc
vendored
Normal file
636
BeefySysLib/third_party/sparsehash/type_traits_unittest.cc
vendored
Normal file
|
@ -0,0 +1,636 @@
|
|||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// ----
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include <config.h>
|
||||
#include <sparsehash/type_traits.h>
|
||||
|
||||
#include <stdlib.h> // for exit()
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "testutil.h"
|
||||
|
||||
typedef int int32;
|
||||
typedef long int64;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::pair;
|
||||
|
||||
using GOOGLE_NAMESPACE::add_reference;
|
||||
using GOOGLE_NAMESPACE::has_trivial_assign;
|
||||
using GOOGLE_NAMESPACE::has_trivial_constructor;
|
||||
using GOOGLE_NAMESPACE::has_trivial_copy;
|
||||
using GOOGLE_NAMESPACE::has_trivial_destructor;
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
using GOOGLE_NAMESPACE::is_convertible;
|
||||
using GOOGLE_NAMESPACE::is_enum;
|
||||
#endif
|
||||
using GOOGLE_NAMESPACE::is_floating_point;
|
||||
using GOOGLE_NAMESPACE::is_integral;
|
||||
using GOOGLE_NAMESPACE::is_pointer;
|
||||
using GOOGLE_NAMESPACE::is_pod;
|
||||
using GOOGLE_NAMESPACE::is_reference;
|
||||
using GOOGLE_NAMESPACE::is_same;
|
||||
using GOOGLE_NAMESPACE::remove_const;
|
||||
using GOOGLE_NAMESPACE::remove_cv;
|
||||
using GOOGLE_NAMESPACE::remove_pointer;
|
||||
using GOOGLE_NAMESPACE::remove_reference;
|
||||
using GOOGLE_NAMESPACE::remove_volatile;
|
||||
|
||||
|
||||
// This assertion produces errors like "error: invalid use of
|
||||
// incomplete type 'struct <unnamed>::AssertTypesEq<const int, int>'"
|
||||
// when it fails.
|
||||
template<typename T, typename U> struct AssertTypesEq;
|
||||
template<typename T> struct AssertTypesEq<T, T> {};
|
||||
#define COMPILE_ASSERT_TYPES_EQ(T, U) static_cast<void>(AssertTypesEq<T, U>())
|
||||
|
||||
// A user-defined POD type.
|
||||
struct A {
|
||||
int n_;
|
||||
};
|
||||
|
||||
// A user-defined non-POD type with a trivial copy constructor.
|
||||
class B {
|
||||
public:
|
||||
explicit B(int n) : n_(n) { }
|
||||
private:
|
||||
int n_;
|
||||
};
|
||||
|
||||
// Another user-defined non-POD type with a trivial copy constructor.
|
||||
// We will explicitly declare C to have a trivial copy constructor
|
||||
// by specializing has_trivial_copy.
|
||||
class C {
|
||||
public:
|
||||
explicit C(int n) : n_(n) { }
|
||||
private:
|
||||
int n_;
|
||||
};
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
template<> struct has_trivial_copy<C> : true_type { };
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
// Another user-defined non-POD type with a trivial assignment operator.
|
||||
// We will explicitly declare C to have a trivial assignment operator
|
||||
// by specializing has_trivial_assign.
|
||||
class D {
|
||||
public:
|
||||
explicit D(int n) : n_(n) { }
|
||||
private:
|
||||
int n_;
|
||||
};
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
template<> struct has_trivial_assign<D> : true_type { };
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
// Another user-defined non-POD type with a trivial constructor.
|
||||
// We will explicitly declare E to have a trivial constructor
|
||||
// by specializing has_trivial_constructor.
|
||||
class E {
|
||||
public:
|
||||
int n_;
|
||||
};
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
template<> struct has_trivial_constructor<E> : true_type { };
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
// Another user-defined non-POD type with a trivial destructor.
|
||||
// We will explicitly declare E to have a trivial destructor
|
||||
// by specializing has_trivial_destructor.
|
||||
class F {
|
||||
public:
|
||||
explicit F(int n) : n_(n) { }
|
||||
private:
|
||||
int n_;
|
||||
};
|
||||
|
||||
_START_GOOGLE_NAMESPACE_
|
||||
template<> struct has_trivial_destructor<F> : true_type { };
|
||||
_END_GOOGLE_NAMESPACE_
|
||||
|
||||
enum G {};
|
||||
|
||||
union H {};
|
||||
|
||||
class I {
|
||||
public:
|
||||
operator int() const;
|
||||
};
|
||||
|
||||
class J {
|
||||
private:
|
||||
operator int() const;
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
// A base class and a derived class that inherits from it, used for
|
||||
// testing conversion type traits.
|
||||
class Base {
|
||||
public:
|
||||
virtual ~Base() { }
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
};
|
||||
|
||||
TEST(TypeTraitsTest, TestIsInteger) {
|
||||
// Verify that is_integral is true for all integer types.
|
||||
EXPECT_TRUE(is_integral<bool>::value);
|
||||
EXPECT_TRUE(is_integral<char>::value);
|
||||
EXPECT_TRUE(is_integral<unsigned char>::value);
|
||||
EXPECT_TRUE(is_integral<signed char>::value);
|
||||
EXPECT_TRUE(is_integral<wchar_t>::value);
|
||||
EXPECT_TRUE(is_integral<int>::value);
|
||||
EXPECT_TRUE(is_integral<unsigned int>::value);
|
||||
EXPECT_TRUE(is_integral<short>::value);
|
||||
EXPECT_TRUE(is_integral<unsigned short>::value);
|
||||
EXPECT_TRUE(is_integral<long>::value);
|
||||
EXPECT_TRUE(is_integral<unsigned long>::value);
|
||||
|
||||
// Verify that is_integral is false for a few non-integer types.
|
||||
EXPECT_FALSE(is_integral<void>::value);
|
||||
EXPECT_FALSE(is_integral<float>::value);
|
||||
EXPECT_FALSE(is_integral<string>::value);
|
||||
EXPECT_FALSE(is_integral<int*>::value);
|
||||
EXPECT_FALSE(is_integral<A>::value);
|
||||
EXPECT_FALSE((is_integral<pair<int, int> >::value));
|
||||
|
||||
// Verify that cv-qualified integral types are still integral, and
|
||||
// cv-qualified non-integral types are still non-integral.
|
||||
EXPECT_TRUE(is_integral<const char>::value);
|
||||
EXPECT_TRUE(is_integral<volatile bool>::value);
|
||||
EXPECT_TRUE(is_integral<const volatile unsigned int>::value);
|
||||
EXPECT_FALSE(is_integral<const float>::value);
|
||||
EXPECT_FALSE(is_integral<int* volatile>::value);
|
||||
EXPECT_FALSE(is_integral<const volatile string>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsFloating) {
|
||||
// Verify that is_floating_point is true for all floating-point types.
|
||||
EXPECT_TRUE(is_floating_point<float>::value);
|
||||
EXPECT_TRUE(is_floating_point<double>::value);
|
||||
EXPECT_TRUE(is_floating_point<long double>::value);
|
||||
|
||||
// Verify that is_floating_point is false for a few non-float types.
|
||||
EXPECT_FALSE(is_floating_point<void>::value);
|
||||
EXPECT_FALSE(is_floating_point<long>::value);
|
||||
EXPECT_FALSE(is_floating_point<string>::value);
|
||||
EXPECT_FALSE(is_floating_point<float*>::value);
|
||||
EXPECT_FALSE(is_floating_point<A>::value);
|
||||
EXPECT_FALSE((is_floating_point<pair<int, int> >::value));
|
||||
|
||||
// Verify that cv-qualified floating point types are still floating, and
|
||||
// cv-qualified non-floating types are still non-floating.
|
||||
EXPECT_TRUE(is_floating_point<const float>::value);
|
||||
EXPECT_TRUE(is_floating_point<volatile double>::value);
|
||||
EXPECT_TRUE(is_floating_point<const volatile long double>::value);
|
||||
EXPECT_FALSE(is_floating_point<const int>::value);
|
||||
EXPECT_FALSE(is_floating_point<volatile string>::value);
|
||||
EXPECT_FALSE(is_floating_point<const volatile char>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsPointer) {
|
||||
// Verify that is_pointer is true for some pointer types.
|
||||
EXPECT_TRUE(is_pointer<int*>::value);
|
||||
EXPECT_TRUE(is_pointer<void*>::value);
|
||||
EXPECT_TRUE(is_pointer<string*>::value);
|
||||
EXPECT_TRUE(is_pointer<const void*>::value);
|
||||
EXPECT_TRUE(is_pointer<volatile float* const*>::value);
|
||||
|
||||
// Verify that is_pointer is false for some non-pointer types.
|
||||
EXPECT_FALSE(is_pointer<void>::value);
|
||||
EXPECT_FALSE(is_pointer<float&>::value);
|
||||
EXPECT_FALSE(is_pointer<long>::value);
|
||||
EXPECT_FALSE(is_pointer<vector<int*> >::value);
|
||||
EXPECT_FALSE(is_pointer<int[5]>::value);
|
||||
|
||||
// A function pointer is a pointer, but a function type, or a function
|
||||
// reference type, is not.
|
||||
EXPECT_TRUE(is_pointer<int (*)(int x)>::value);
|
||||
EXPECT_FALSE(is_pointer<void(char x)>::value);
|
||||
EXPECT_FALSE(is_pointer<double (&)(string x)>::value);
|
||||
|
||||
// Verify that is_pointer<T> is true for some cv-qualified pointer types,
|
||||
// and false for some cv-qualified non-pointer types.
|
||||
EXPECT_TRUE(is_pointer<int* const>::value);
|
||||
EXPECT_TRUE(is_pointer<const void* volatile>::value);
|
||||
EXPECT_TRUE(is_pointer<char** const volatile>::value);
|
||||
EXPECT_FALSE(is_pointer<const int>::value);
|
||||
EXPECT_FALSE(is_pointer<volatile vector<int*> >::value);
|
||||
EXPECT_FALSE(is_pointer<const volatile double>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsEnum) {
|
||||
// is_enum isn't supported on MSVC or gcc 3.x
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
// Verify that is_enum is true for enum types.
|
||||
EXPECT_TRUE(is_enum<G>::value);
|
||||
EXPECT_TRUE(is_enum<const G>::value);
|
||||
EXPECT_TRUE(is_enum<volatile G>::value);
|
||||
EXPECT_TRUE(is_enum<const volatile G>::value);
|
||||
|
||||
// Verify that is_enum is false for a few non-enum types.
|
||||
EXPECT_FALSE(is_enum<void>::value);
|
||||
EXPECT_FALSE(is_enum<G&>::value);
|
||||
EXPECT_FALSE(is_enum<G[1]>::value);
|
||||
EXPECT_FALSE(is_enum<const G[1]>::value);
|
||||
EXPECT_FALSE(is_enum<G[]>::value);
|
||||
EXPECT_FALSE(is_enum<int>::value);
|
||||
EXPECT_FALSE(is_enum<float>::value);
|
||||
EXPECT_FALSE(is_enum<A>::value);
|
||||
EXPECT_FALSE(is_enum<A*>::value);
|
||||
EXPECT_FALSE(is_enum<const A>::value);
|
||||
EXPECT_FALSE(is_enum<H>::value);
|
||||
EXPECT_FALSE(is_enum<I>::value);
|
||||
EXPECT_FALSE(is_enum<J>::value);
|
||||
EXPECT_FALSE(is_enum<void()>::value);
|
||||
EXPECT_FALSE(is_enum<void(*)()>::value);
|
||||
EXPECT_FALSE(is_enum<int A::*>::value);
|
||||
EXPECT_FALSE(is_enum<void (A::*)()>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsReference) {
|
||||
// Verifies that is_reference is true for all reference types.
|
||||
typedef float& RefFloat;
|
||||
EXPECT_TRUE(is_reference<float&>::value);
|
||||
EXPECT_TRUE(is_reference<const int&>::value);
|
||||
EXPECT_TRUE(is_reference<const int*&>::value);
|
||||
EXPECT_TRUE(is_reference<int (&)(bool)>::value);
|
||||
EXPECT_TRUE(is_reference<RefFloat>::value);
|
||||
EXPECT_TRUE(is_reference<const RefFloat>::value);
|
||||
EXPECT_TRUE(is_reference<volatile RefFloat>::value);
|
||||
EXPECT_TRUE(is_reference<const volatile RefFloat>::value);
|
||||
|
||||
|
||||
// Verifies that is_reference is false for all non-reference types.
|
||||
EXPECT_FALSE(is_reference<float>::value);
|
||||
EXPECT_FALSE(is_reference<const float>::value);
|
||||
EXPECT_FALSE(is_reference<volatile float>::value);
|
||||
EXPECT_FALSE(is_reference<const volatile float>::value);
|
||||
EXPECT_FALSE(is_reference<const int*>::value);
|
||||
EXPECT_FALSE(is_reference<int()>::value);
|
||||
EXPECT_FALSE(is_reference<void(*)(const char&)>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestAddReference) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(volatile int&,
|
||||
add_reference<volatile int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const volatile int&,
|
||||
add_reference<const volatile int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int&, add_reference<int&>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const int&, add_reference<const int&>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(volatile int&,
|
||||
add_reference<volatile int&>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const volatile int&,
|
||||
add_reference<const volatile int&>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsPod) {
|
||||
// Verify that arithmetic types and pointers are marked as PODs.
|
||||
EXPECT_TRUE(is_pod<bool>::value);
|
||||
EXPECT_TRUE(is_pod<char>::value);
|
||||
EXPECT_TRUE(is_pod<unsigned char>::value);
|
||||
EXPECT_TRUE(is_pod<signed char>::value);
|
||||
EXPECT_TRUE(is_pod<wchar_t>::value);
|
||||
EXPECT_TRUE(is_pod<int>::value);
|
||||
EXPECT_TRUE(is_pod<unsigned int>::value);
|
||||
EXPECT_TRUE(is_pod<short>::value);
|
||||
EXPECT_TRUE(is_pod<unsigned short>::value);
|
||||
EXPECT_TRUE(is_pod<long>::value);
|
||||
EXPECT_TRUE(is_pod<unsigned long>::value);
|
||||
EXPECT_TRUE(is_pod<float>::value);
|
||||
EXPECT_TRUE(is_pod<double>::value);
|
||||
EXPECT_TRUE(is_pod<long double>::value);
|
||||
EXPECT_TRUE(is_pod<string*>::value);
|
||||
EXPECT_TRUE(is_pod<A*>::value);
|
||||
EXPECT_TRUE(is_pod<const B*>::value);
|
||||
EXPECT_TRUE(is_pod<C**>::value);
|
||||
EXPECT_TRUE(is_pod<const int>::value);
|
||||
EXPECT_TRUE(is_pod<char* volatile>::value);
|
||||
EXPECT_TRUE(is_pod<const volatile double>::value);
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
EXPECT_TRUE(is_pod<G>::value);
|
||||
EXPECT_TRUE(is_pod<const G>::value);
|
||||
EXPECT_TRUE(is_pod<volatile G>::value);
|
||||
EXPECT_TRUE(is_pod<const volatile G>::value);
|
||||
#endif
|
||||
|
||||
// Verify that some non-POD types are not marked as PODs.
|
||||
EXPECT_FALSE(is_pod<void>::value);
|
||||
EXPECT_FALSE(is_pod<string>::value);
|
||||
EXPECT_FALSE((is_pod<pair<int, int> >::value));
|
||||
EXPECT_FALSE(is_pod<A>::value);
|
||||
EXPECT_FALSE(is_pod<B>::value);
|
||||
EXPECT_FALSE(is_pod<C>::value);
|
||||
EXPECT_FALSE(is_pod<const string>::value);
|
||||
EXPECT_FALSE(is_pod<volatile A>::value);
|
||||
EXPECT_FALSE(is_pod<const volatile B>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestHasTrivialConstructor) {
|
||||
// Verify that arithmetic types and pointers have trivial constructors.
|
||||
EXPECT_TRUE(has_trivial_constructor<bool>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<char>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<unsigned char>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<signed char>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<wchar_t>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<int>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<unsigned int>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<short>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<unsigned short>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<long>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<unsigned long>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<float>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<double>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<long double>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<string*>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<A*>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<const B*>::value);
|
||||
EXPECT_TRUE(has_trivial_constructor<C**>::value);
|
||||
|
||||
// Verify that pairs and arrays of such types have trivial
|
||||
// constructors.
|
||||
typedef int int10[10];
|
||||
EXPECT_TRUE((has_trivial_constructor<pair<int, char*> >::value));
|
||||
EXPECT_TRUE(has_trivial_constructor<int10>::value);
|
||||
|
||||
// Verify that pairs of types without trivial constructors
|
||||
// are not marked as trivial.
|
||||
EXPECT_FALSE((has_trivial_constructor<pair<int, string> >::value));
|
||||
EXPECT_FALSE((has_trivial_constructor<pair<string, int> >::value));
|
||||
|
||||
// Verify that types without trivial constructors are
|
||||
// correctly marked as such.
|
||||
EXPECT_FALSE(has_trivial_constructor<string>::value);
|
||||
EXPECT_FALSE(has_trivial_constructor<vector<int> >::value);
|
||||
|
||||
// Verify that E, which we have declared to have a trivial
|
||||
// constructor, is correctly marked as such.
|
||||
EXPECT_TRUE(has_trivial_constructor<E>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestHasTrivialCopy) {
|
||||
// Verify that arithmetic types and pointers have trivial copy
|
||||
// constructors.
|
||||
EXPECT_TRUE(has_trivial_copy<bool>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<char>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<unsigned char>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<signed char>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<wchar_t>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<int>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<unsigned int>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<short>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<unsigned short>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<long>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<unsigned long>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<float>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<double>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<long double>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<string*>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<A*>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<const B*>::value);
|
||||
EXPECT_TRUE(has_trivial_copy<C**>::value);
|
||||
|
||||
// Verify that pairs and arrays of such types have trivial
|
||||
// copy constructors.
|
||||
typedef int int10[10];
|
||||
EXPECT_TRUE((has_trivial_copy<pair<int, char*> >::value));
|
||||
EXPECT_TRUE(has_trivial_copy<int10>::value);
|
||||
|
||||
// Verify that pairs of types without trivial copy constructors
|
||||
// are not marked as trivial.
|
||||
EXPECT_FALSE((has_trivial_copy<pair<int, string> >::value));
|
||||
EXPECT_FALSE((has_trivial_copy<pair<string, int> >::value));
|
||||
|
||||
// Verify that types without trivial copy constructors are
|
||||
// correctly marked as such.
|
||||
EXPECT_FALSE(has_trivial_copy<string>::value);
|
||||
EXPECT_FALSE(has_trivial_copy<vector<int> >::value);
|
||||
|
||||
// Verify that C, which we have declared to have a trivial
|
||||
// copy constructor, is correctly marked as such.
|
||||
EXPECT_TRUE(has_trivial_copy<C>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestHasTrivialAssign) {
|
||||
// Verify that arithmetic types and pointers have trivial assignment
|
||||
// operators.
|
||||
EXPECT_TRUE(has_trivial_assign<bool>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<char>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<unsigned char>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<signed char>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<wchar_t>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<int>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<unsigned int>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<short>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<unsigned short>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<long>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<unsigned long>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<float>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<double>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<long double>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<string*>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<A*>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<const B*>::value);
|
||||
EXPECT_TRUE(has_trivial_assign<C**>::value);
|
||||
|
||||
// Verify that pairs and arrays of such types have trivial
|
||||
// assignment operators.
|
||||
typedef int int10[10];
|
||||
EXPECT_TRUE((has_trivial_assign<pair<int, char*> >::value));
|
||||
EXPECT_TRUE(has_trivial_assign<int10>::value);
|
||||
|
||||
// Verify that pairs of types without trivial assignment operators
|
||||
// are not marked as trivial.
|
||||
EXPECT_FALSE((has_trivial_assign<pair<int, string> >::value));
|
||||
EXPECT_FALSE((has_trivial_assign<pair<string, int> >::value));
|
||||
|
||||
// Verify that types without trivial assignment operators are
|
||||
// correctly marked as such.
|
||||
EXPECT_FALSE(has_trivial_assign<string>::value);
|
||||
EXPECT_FALSE(has_trivial_assign<vector<int> >::value);
|
||||
|
||||
// Verify that D, which we have declared to have a trivial
|
||||
// assignment operator, is correctly marked as such.
|
||||
EXPECT_TRUE(has_trivial_assign<D>::value);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestHasTrivialDestructor) {
|
||||
// Verify that arithmetic types and pointers have trivial destructors.
|
||||
EXPECT_TRUE(has_trivial_destructor<bool>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<char>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<unsigned char>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<signed char>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<wchar_t>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<int>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<unsigned int>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<short>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<unsigned short>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<long>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<unsigned long>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<float>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<double>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<long double>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<string*>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<A*>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<const B*>::value);
|
||||
EXPECT_TRUE(has_trivial_destructor<C**>::value);
|
||||
|
||||
// Verify that pairs and arrays of such types have trivial
|
||||
// destructors.
|
||||
typedef int int10[10];
|
||||
EXPECT_TRUE((has_trivial_destructor<pair<int, char*> >::value));
|
||||
EXPECT_TRUE(has_trivial_destructor<int10>::value);
|
||||
|
||||
// Verify that pairs of types without trivial destructors
|
||||
// are not marked as trivial.
|
||||
EXPECT_FALSE((has_trivial_destructor<pair<int, string> >::value));
|
||||
EXPECT_FALSE((has_trivial_destructor<pair<string, int> >::value));
|
||||
|
||||
// Verify that types without trivial destructors are
|
||||
// correctly marked as such.
|
||||
EXPECT_FALSE(has_trivial_destructor<string>::value);
|
||||
EXPECT_FALSE(has_trivial_destructor<vector<int> >::value);
|
||||
|
||||
// Verify that F, which we have declared to have a trivial
|
||||
// destructor, is correctly marked as such.
|
||||
EXPECT_TRUE(has_trivial_destructor<F>::value);
|
||||
}
|
||||
|
||||
// Tests remove_pointer.
|
||||
TEST(TypeTraitsTest, TestRemovePointer) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int*>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const int, remove_pointer<const int*>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* const>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_pointer<int* volatile>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestRemoveConst) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_const<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_const<const int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int *, remove_const<int * const>::type);
|
||||
// TR1 examples.
|
||||
COMPILE_ASSERT_TYPES_EQ(const int *, remove_const<const int *>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(volatile int,
|
||||
remove_const<const volatile int>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestRemoveVolatile) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_volatile<volatile int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int *, remove_volatile<int * volatile>::type);
|
||||
// TR1 examples.
|
||||
COMPILE_ASSERT_TYPES_EQ(volatile int *,
|
||||
remove_volatile<volatile int *>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const int,
|
||||
remove_volatile<const volatile int>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestRemoveCV) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_cv<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_cv<volatile int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_cv<const int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int *, remove_cv<int * const volatile>::type);
|
||||
// TR1 examples.
|
||||
COMPILE_ASSERT_TYPES_EQ(const volatile int *,
|
||||
remove_cv<const volatile int *>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int,
|
||||
remove_cv<const volatile int>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestRemoveReference) {
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int, remove_reference<int&>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(const int, remove_reference<const int&>::type);
|
||||
COMPILE_ASSERT_TYPES_EQ(int*, remove_reference<int * &>::type);
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestIsSame) {
|
||||
EXPECT_TRUE((is_same<int32, int32>::value));
|
||||
EXPECT_FALSE((is_same<int32, int64>::value));
|
||||
EXPECT_FALSE((is_same<int64, int32>::value));
|
||||
EXPECT_FALSE((is_same<int, const int>::value));
|
||||
|
||||
EXPECT_TRUE((is_same<void, void>::value));
|
||||
EXPECT_FALSE((is_same<void, int>::value));
|
||||
EXPECT_FALSE((is_same<int, void>::value));
|
||||
|
||||
EXPECT_TRUE((is_same<int*, int*>::value));
|
||||
EXPECT_TRUE((is_same<void*, void*>::value));
|
||||
EXPECT_FALSE((is_same<int*, void*>::value));
|
||||
EXPECT_FALSE((is_same<void*, int*>::value));
|
||||
EXPECT_FALSE((is_same<void*, const void*>::value));
|
||||
EXPECT_FALSE((is_same<void*, void* const>::value));
|
||||
|
||||
EXPECT_TRUE((is_same<Base*, Base*>::value));
|
||||
EXPECT_TRUE((is_same<Derived*, Derived*>::value));
|
||||
EXPECT_FALSE((is_same<Base*, Derived*>::value));
|
||||
EXPECT_FALSE((is_same<Derived*, Base*>::value));
|
||||
}
|
||||
|
||||
TEST(TypeTraitsTest, TestConvertible) {
|
||||
#if !defined(_MSC_VER) && !(defined(__GNUC__) && __GNUC__ <= 3)
|
||||
EXPECT_TRUE((is_convertible<int, int>::value));
|
||||
EXPECT_TRUE((is_convertible<int, long>::value));
|
||||
EXPECT_TRUE((is_convertible<long, int>::value));
|
||||
|
||||
EXPECT_TRUE((is_convertible<int*, void*>::value));
|
||||
EXPECT_FALSE((is_convertible<void*, int*>::value));
|
||||
|
||||
EXPECT_TRUE((is_convertible<Derived*, Base*>::value));
|
||||
EXPECT_FALSE((is_convertible<Base*, Derived*>::value));
|
||||
EXPECT_TRUE((is_convertible<Derived*, const Base*>::value));
|
||||
EXPECT_FALSE((is_convertible<const Derived*, Base*>::value));
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int main(int, char **) {
|
||||
// All the work is done in the static constructors. If they don't
|
||||
// die, the tests have all passed.
|
||||
std::cout << "PASS\n";
|
||||
return 0;
|
||||
}
|
||||
|
173
BeefySysLib/third_party/sparsehash/windows/config.h
vendored
Normal file
173
BeefySysLib/third_party/sparsehash/windows/config.h
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
#ifndef GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_
|
||||
#define GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_
|
||||
|
||||
/* src/config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Namespace for Google classes */
|
||||
#define GOOGLE_NAMESPACE ::google
|
||||
|
||||
#if (_MSC_VER >= 1800 )
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#define HASH_FUN_H <unordered_map>
|
||||
|
||||
/* the location of <unordered_map> or <hash_map> */
|
||||
#define HASH_MAP_H <unordered_map>
|
||||
|
||||
/* the location of <unordered_set> or <hash_set> */
|
||||
#define HASH_SET_H <unordered_set>
|
||||
|
||||
/* define if the compiler has hash_map */
|
||||
#define HAVE_HASH_MAP 0
|
||||
|
||||
/* define if the compiler has hash_set */
|
||||
#define HAVE_HASH_SET 0
|
||||
|
||||
/* define if the compiler supports unordered_{map,set} */
|
||||
#define HAVE_UNORDERED_MAP 1
|
||||
|
||||
#else /* Earlier than VSC++ 2013 */
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#define HASH_FUN_H <hash_map>
|
||||
|
||||
/* the location of <unordered_map> or <hash_map> */
|
||||
#define HASH_MAP_H <hash_map>
|
||||
|
||||
/* the location of <unordered_set> or <hash_set> */
|
||||
#define HASH_SET_H <hash_set>
|
||||
|
||||
/* define if the compiler has hash_map */
|
||||
#define HAVE_HASH_MAP 1
|
||||
|
||||
/* define if the compiler has hash_set */
|
||||
#define HAVE_HASH_SET 1
|
||||
|
||||
/* define if the compiler supports unordered_{map,set} */
|
||||
#undef HAVE_UNORDERED_MAP
|
||||
|
||||
#endif
|
||||
|
||||
/* the namespace of the hash<> function */
|
||||
#define HASH_NAMESPACE stdext
|
||||
|
||||
/* Define to 1 if you have the <google/malloc_extension.h> header file. */
|
||||
#undef HAVE_GOOGLE_MALLOC_EXTENSION_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#define HAVE_MEMMOVE 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* define if the compiler implements namespaces */
|
||||
#define HAVE_NAMESPACES 1
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#undef HAVE_SYS_UTSNAME_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if the system has the type `u_int16_t'. */
|
||||
#undef HAVE_U_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `__uint16'. */
|
||||
#define HAVE___UINT16 1
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
#undef PTHREAD_CREATE_JOINABLE
|
||||
|
||||
/* The system-provided hash function including the namespace. */
|
||||
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
|
||||
|
||||
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
|
||||
#define SPARSEHASH_HASH_NO_NAMESPACE hash_compare
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Stops putting the code inside the Google namespace */
|
||||
#define _END_GOOGLE_NAMESPACE_ }
|
||||
|
||||
/* Puts following code inside the Google namespace */
|
||||
#define _START_GOOGLE_NAMESPACE_ namespace google {
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Extra stuff not found in config.h.in
|
||||
|
||||
#define HAVE_WINDOWS_H 1 // used in time_hash_map
|
||||
|
||||
// This makes sure the definitions in config.h and sparseconfig.h match
|
||||
// up. If they don't, the compiler will complain about redefinition.
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
|
||||
// TODO(csilvers): include windows/port.h in every relevant source file instead?
|
||||
#include "windows/port.h"
|
||||
|
||||
#endif /* GOOGLE_SPARSEHASH_WINDOWS_CONFIG_H_ */
|
49
BeefySysLib/third_party/sparsehash/windows/google/sparsehash/sparseconfig.h
vendored
Normal file
49
BeefySysLib/third_party/sparsehash/windows/google/sparsehash/sparseconfig.h
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* NOTE: This file is for internal use only.
|
||||
* Do not use these #defines in your own program!
|
||||
*/
|
||||
|
||||
/* Namespace for Google classes */
|
||||
#define GOOGLE_NAMESPACE ::google
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#define HASH_FUN_H <hash_map>
|
||||
|
||||
/* the namespace of the hash<> function */
|
||||
#define HASH_NAMESPACE stdext
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `u_int16_t'. */
|
||||
#undef HAVE_U_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `__uint16'. */
|
||||
#define HAVE___UINT16 1
|
||||
|
||||
/* The system-provided hash function including the namespace. */
|
||||
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
|
||||
|
||||
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
|
||||
#define SPARSEHASH_HASH_NO_NAMESPACE hash_compare
|
||||
|
||||
/* Stops putting the code inside the Google namespace */
|
||||
#define _END_GOOGLE_NAMESPACE_ }
|
||||
|
||||
/* Puts following code inside the Google namespace */
|
||||
#define _START_GOOGLE_NAMESPACE_ namespace google {
|
64
BeefySysLib/third_party/sparsehash/windows/port.cc
vendored
Normal file
64
BeefySysLib/third_party/sparsehash/windows/port.cc
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Copyright (c) 2007, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ---
|
||||
* Author: Craig Silverstein
|
||||
*/
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#ifndef WIN32
|
||||
# error You should only be including windows/port.cc in a windows environment!
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include <stdarg.h> // for va_list, va_start, va_end
|
||||
#include "port.h"
|
||||
|
||||
// Calls the windows _vsnprintf, but always NUL-terminate.
|
||||
int snprintf(char *str, size_t size, const char *format, ...) {
|
||||
if (size == 0) // not even room for a \0?
|
||||
return -1; // not what C99 says to do, but what windows does
|
||||
str[size-1] = '\0';
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
const int r = _vsnprintf(str, size-1, format, ap);
|
||||
va_end(ap);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string TmpFile(const char* basename) {
|
||||
char tmppath_buffer[1024];
|
||||
int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
|
||||
if (tmppath_len <= 0 || tmppath_len >= sizeof(tmppath_buffer)) {
|
||||
return basename; // an error, so just bail on tmppath
|
||||
}
|
||||
snprintf(tmppath_buffer + tmppath_len, sizeof(tmppath_buffer) - tmppath_len,
|
||||
"\\%s", basename);
|
||||
return tmppath_buffer;
|
||||
}
|
72
BeefySysLib/third_party/sparsehash/windows/port.h
vendored
Normal file
72
BeefySysLib/third_party/sparsehash/windows/port.h
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (c) 2007, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ---
|
||||
* Author: Craig Silverstein
|
||||
*
|
||||
* These are some portability typedefs and defines to make it a bit
|
||||
* easier to compile this code -- in particular, unittests -- under VC++.
|
||||
* Other portability code is found in windows/sparsehash/internal/sparseconfig.h.
|
||||
*
|
||||
* Several of these are taken from glib:
|
||||
* http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html
|
||||
*/
|
||||
|
||||
#ifndef SPARSEHASH_WINDOWS_PORT_H_
|
||||
#define SPARSEHASH_WINDOWS_PORT_H_
|
||||
|
||||
#include <sparsehash/internal/sparseconfig.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */
|
||||
#include <windows.h>
|
||||
#include <io.h> /* because we so often use open/close/etc */
|
||||
#include <string>
|
||||
|
||||
// 4996: Yes, we're ok using the "unsafe" functions like _vsnprintf and fopen
|
||||
// 4127: We use "while (1)" sometimes: yes, we know it's a constant
|
||||
// 4181: type_traits_test is explicitly testing 'qualifier applied to reference'
|
||||
#pragma warning(disable:4996 4127 4181)
|
||||
|
||||
|
||||
// file I/O
|
||||
#define unlink _unlink
|
||||
#define strdup _strdup
|
||||
|
||||
// We can't just use _snprintf as a drop-in replacement, because it
|
||||
// doesn't always NUL-terminate. :-(
|
||||
extern int snprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
extern std::string TmpFile(const char* basename); // used in hashtable_unittest
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* SPARSEHASH_WINDOWS_PORT_H_ */
|
58
BeefySysLib/third_party/sparsehash/windows/sparsehash/internal/sparseconfig.h
vendored
Normal file
58
BeefySysLib/third_party/sparsehash/windows/sparsehash/internal/sparseconfig.h
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* NOTE: This file is for internal use only.
|
||||
* Do not use these #defines in your own program!
|
||||
*/
|
||||
|
||||
/* Namespace for Google classes */
|
||||
#define GOOGLE_NAMESPACE ::google
|
||||
|
||||
#if (_MSC_VER >= 1800 )
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#define HASH_FUN_H <unordered_map>
|
||||
|
||||
#else /* Earlier than VSC++ 2013 */
|
||||
|
||||
/* the location of the header defining hash functions */
|
||||
#define HASH_FUN_H <hash_map>
|
||||
|
||||
#endif
|
||||
|
||||
/* the namespace of the hash<> function */
|
||||
#define HASH_NAMESPACE stdext
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `u_int16_t'. */
|
||||
#undef HAVE_U_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `__uint16'. */
|
||||
#define HAVE___UINT16 1
|
||||
|
||||
/* The system-provided hash function including the namespace. */
|
||||
#define SPARSEHASH_HASH HASH_NAMESPACE::hash_compare
|
||||
|
||||
/* The system-provided hash function, in namespace HASH_NAMESPACE. */
|
||||
#define SPARSEHASH_HASH_NO_NAMESPACE hash_compare
|
||||
|
||||
/* Stops putting the code inside the Google namespace */
|
||||
#define _END_GOOGLE_NAMESPACE_ }
|
||||
|
||||
/* Puts following code inside the Google namespace */
|
||||
#define _START_GOOGLE_NAMESPACE_ namespace google {
|
Loading…
Add table
Add a link
Reference in a new issue