commit 5448d1b00ad427d043237ca5c6d8e78970ac2ec4 Author: CentOS Sources Date: Wed Dec 16 11:40:26 2020 +0000 import kyotocabinet-1.2.76-17.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c14b9ac --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/kyotocabinet-1.2.76.tar.gz diff --git a/.kyotocabinet.metadata b/.kyotocabinet.metadata new file mode 100644 index 0000000..e874e26 --- /dev/null +++ b/.kyotocabinet.metadata @@ -0,0 +1 @@ +a4ec70d08ca6c8f510dbc329d5c27b55030d3521 SOURCES/kyotocabinet-1.2.76.tar.gz diff --git a/SOURCES/kyotocabinet-1.2.76-8-byte-atomics.patch b/SOURCES/kyotocabinet-1.2.76-8-byte-atomics.patch new file mode 100644 index 0000000..f9417e9 --- /dev/null +++ b/SOURCES/kyotocabinet-1.2.76-8-byte-atomics.patch @@ -0,0 +1,74 @@ +Patch by Shawn Landden for kyotocabinet >= 1.2.76, which fixes +the configure test to handle lack of 8 byte atomics correctly as is the case with ARM 32 +bit on all Fedora releases, Intel 32 bit on RHEL 5 and PowerPC 32 bit on RHEL 5 and all +Fedora releases. + +--- kyotocabinet-1.2.76/configure.in 2012-05-24 13:31:42.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.in.8-byte-atomics 2013-03-01 00:21:21.000000000 +0100 +@@ -238,9 +238,22 @@ + # Atomic operations + if test "$enable_atomic" != "no" + then +- printf 'checking for atomic operations... ' +- AC_TRY_COMPILE([], [__sync_fetch_and_add], [MYGCCATOMIC=yes], [MYGCCATOMIC=no]) +- if test "$MYGCCATOMIC" = "yes" ++ printf 'checking for 8 byte atomic operations... ' ++ if printf ' ++/* Some targets support 4 byte atomics, but not 8 byte atomics, ++ * and will fail at link time if they are used. ++ * ++ * http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Atomic-Builtins.html ++ * http://gcc.gnu.org/wiki/Atomic ++ */ ++#include ++int ++main () ++{ ++uint64_t n = 0xdeadbeaf; ++__sync_bool_compare_and_swap(&n, 0xdeadbeaf, 0); ++return n; ++}' | $CC -xc -o config.tmp - >/dev/null 2>&1 + then + MYCPPFLAGS="$MYCPPFLAGS -D_MYGCCATOMIC" + printf 'yes\n' +--- kyotocabinet-1.2.76/configure 2012-05-24 13:31:45.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.8-byte-atomics 2013-03-01 00:22:37.000000000 +0100 +@@ -4012,25 +4012,22 @@ + # Atomic operations + if test "$enable_atomic" != "no" + then +- printf 'checking for atomic operations... ' +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- ++ printf 'checking for 8 byte atomic operations... ' ++ if printf ' ++/* Some targets support 4 byte atomics, but not 8 byte atomics, ++ * and will fail at link time if they are used. ++ * ++ * http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Atomic-Builtins.html ++ * http://gcc.gnu.org/wiki/Atomic ++ */ ++#include + int + main () + { +-__sync_fetch_and_add +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_cxx_try_compile "$LINENO"; then : +- MYGCCATOMIC=yes +-else +- MYGCCATOMIC=no +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +- if test "$MYGCCATOMIC" = "yes" ++uint64_t n = 0xdeadbeaf; ++__sync_bool_compare_and_swap(&n, 0xdeadbeaf, 0); ++return n; ++}' | $CC -xc -o config.tmp - >/dev/null 2>&1 + then + MYCPPFLAGS="$MYCPPFLAGS -D_MYGCCATOMIC" + printf 'yes\n' diff --git a/SOURCES/kyotocabinet-1.2.76-cflags.patch b/SOURCES/kyotocabinet-1.2.76-cflags.patch new file mode 100644 index 0000000..861ee93 --- /dev/null +++ b/SOURCES/kyotocabinet-1.2.76-cflags.patch @@ -0,0 +1,90 @@ +Patch by Robert Scheck for kyotocabinet >= 1.2.76 to ensure +that CFLAGS and CXXFLAGS do not include "-g0 -O2" or "-O0" at all as we need debug info +for the -debuginfo RPM packages. Additionally the patch removes "-rpath-link" as well. + +--- kyotocabinet-1.2.76/configure 2012-05-24 13:31:45.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.cflags 2013-11-17 18:28:55.000000000 +0100 +@@ -2109,8 +2109,8 @@ + MYPCFILES="kyotocabinet.pc" + + # Building flags +-MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g0 -O2" +-MYCXXFLAGS="-Wall -fPIC -fsigned-char -g0 -O2" ++MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char" ++MYCXXFLAGS="-Wall -fPIC -fsigned-char" + MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -I/usr/local/include" + MYCPPFLAGS="$MYCPPFLAGS -DNDEBUG -D_GNU_SOURCE=1" + MYCPPFLAGS="$MYCPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -D__EXTENSIONS__" +@@ -2147,8 +2147,8 @@ + + if test "$enable_debug" = "yes" + then +- MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g -O0" +- MYCXXFLAGS="-Wall -fPIC -fsigned-char -g -O0" ++ MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g" ++ MYCXXFLAGS="-Wall -fPIC -fsigned-char -g" + MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG -D_KCDEBUG" + is_static="yes" + enables="$enables (debug)" +@@ -2178,8 +2178,8 @@ + + if test "$enable_opt" = "no" + then +- MYCFLAGS="$MYCFLAGS -O0" +- MYCXXFLAGS="$MYCXXFLAGS -O0" ++ MYCFLAGS="$MYCFLAGS" ++ MYCXXFLAGS="$MYCXXFLAGS" + enables="$enables (no-opt)" + fi + +@@ -4538,7 +4538,6 @@ + # As-needed linking + if uname | grep Linux >config.tmp + then +- MYLDFLAGS="$MYLDFLAGS -Wl,-rpath-link,.:/usr/local/lib:$MYLDLIBPATH" + MYLDFLAGS="$MYLDFLAGS -Wl,--as-needed" + else + MYCMDLIBS="$MYCMDLIBS $LIBS" +--- kyotocabinet-1.2.76/configure.in 2012-05-24 13:31:42.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.in.cflags 2013-11-17 18:29:20.000000000 +0100 +@@ -35,8 +35,8 @@ + MYPCFILES="kyotocabinet.pc" + + # Building flags +-MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g0 -O2" +-MYCXXFLAGS="-Wall -fPIC -fsigned-char -g0 -O2" ++MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char" ++MYCXXFLAGS="-Wall -fPIC -fsigned-char" + MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -I/usr/local/include" + MYCPPFLAGS="$MYCPPFLAGS -DNDEBUG -D_GNU_SOURCE=1" + MYCPPFLAGS="$MYCPPFLAGS -D_FILE_OFFSET_BITS=64 -D_REENTRANT -D__EXTENSIONS__" +@@ -70,8 +70,8 @@ + AC_HELP_STRING([--enable-debug], [build for debugging])) + if test "$enable_debug" = "yes" + then +- MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g -O0" +- MYCXXFLAGS="-Wall -fPIC -fsigned-char -g -O0" ++ MYCFLAGS="-Wall -ansi -pedantic -fPIC -fsigned-char -g" ++ MYCXXFLAGS="-Wall -fPIC -fsigned-char -g" + MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG -D_KCDEBUG" + is_static="yes" + enables="$enables (debug)" +@@ -95,8 +95,8 @@ + AC_HELP_STRING([--disable-opt], [build without optimization])) + if test "$enable_opt" = "no" + then +- MYCFLAGS="$MYCFLAGS -O0" +- MYCXXFLAGS="$MYCXXFLAGS -O0" ++ MYCFLAGS="$MYCFLAGS" ++ MYCXXFLAGS="$MYCXXFLAGS" + enables="$enables (no-opt)" + fi + +@@ -302,7 +302,6 @@ + # As-needed linking + if uname | grep Linux >config.tmp + then +- MYLDFLAGS="$MYLDFLAGS -Wl,-rpath-link,.:/usr/local/lib:$MYLDLIBPATH" + MYLDFLAGS="$MYLDFLAGS -Wl,--as-needed" + else + MYCMDLIBS="$MYCMDLIBS $LIBS" diff --git a/SOURCES/kyotocabinet-1.2.76-gcc6.patch b/SOURCES/kyotocabinet-1.2.76-gcc6.patch new file mode 100644 index 0000000..d565cff --- /dev/null +++ b/SOURCES/kyotocabinet-1.2.76-gcc6.patch @@ -0,0 +1,45 @@ +Patch from Andreas Stührk to work around build +failures with GCC >= 6 like: + +In file included from kcdbext.cc:16:0: +kcdbext.h: In member function 'char* kyotocabinet::IndexDB::get(const char*, size_t, size_t*)': +kcdbext.h:1281:14: error: cannot convert 'bool' to 'char*' in return + return false; + ^~~~~ +In file included from kclangc.cc:17:0: +kcdbext.h: In member function 'char* kyotocabinet::IndexDB::get(const char*, size_t, size_t*)': +kcdbext.h:1281:14: error: cannot convert 'bool' to 'char*' in return + return false; + ^~~~~ + +Note that using '\0' rather nullptr (like the patch from openSUSE is +doing) just leads to new build failures with GCC >= 7 like: + +In file included from kcdbext.cc:16:0: +kcdbext.h: In member function 'char* kyotocabinet::IndexDB::get(const char*, size_t, size_t*)': +kcdbext.h:1281:14: error: invalid conversion from 'char' to 'char*' [-fpermissive] + return '\0'; + ^~~~ +In file included from kclangc.cc:17:0: +kcdbext.h: In member function 'char* kyotocabinet::IndexDB::get(const char*, size_t, size_t*)': +kcdbext.h:1281:14: error: invalid conversion from 'char' to 'char*' [-fpermissive] + return '\0'; + ^~~~ + +See also: + + - https://bugzilla.redhat.com/show_bug.cgi?id=1307706 + - https://build.opensuse.org/package/view_file/devel:libraries:c_c++/kyotocabinet/gcc6-fix-errors.patch?expand=1 + - https://bugs.debian.org/811627 + +--- kyotocabinet-1.2.76/kcdbext.h 2016-05-25 11:32:53.591866016 +0200 ++++ kyotocabinet-1.2.76/kcdbext.h 2012-05-24 18:27:59.000000000 +0200 +@@ -1278,7 +1278,7 @@ + if (omode_ == 0) { + set_error(_KCCODELINE_, BasicDB::Error::INVALID, "not opened"); + *sp = 0; +- return false; ++ return nullptr; + } + if (!cache_) return db_.get(kbuf, ksiz, sp); + size_t dvsiz = 0; diff --git a/SOURCES/kyotocabinet-1.2.76-tr1_hashtable.patch b/SOURCES/kyotocabinet-1.2.76-tr1_hashtable.patch new file mode 100644 index 0000000..d925871 --- /dev/null +++ b/SOURCES/kyotocabinet-1.2.76-tr1_hashtable.patch @@ -0,0 +1,1326 @@ +Workaround by Robert Scheck for kyotocabinet >= 1.2.76, which +avoids the "error: declaration of 'struct std::tr1::hash'" compile errors +when using GCC 4.1.x on Red Hat Enterprise Linux 5 instead of using recommented GCC 4.4.x +(or later) by copying and patching the relevant "/usr/include/c++/4.1.1/tr1/functional" +file. Passing "long long" and "unsigned long long" to tr1_hashtable_define_trivial_hash() +is the key. For further information, also have a look to Red Hat Bugzilla, bug ID #915123: +https://bugzilla.redhat.com/show_bug.cgi?id=915123 + +--- kyotocabinet-1.2.76/configure 2012-05-24 13:31:45.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.tr1_hashtable 2013-11-17 03:11:59.000000000 +0100 +@@ -2090,7 +2090,7 @@ + + # Targets + MYHEADERFILES="kccommon.h kcutil.h kcthread.h kcfile.h" +-MYHEADERFILES="$MYHEADERFILES kccompress.h kccompare.h kcmap.h kcregex.h" ++MYHEADERFILES="$MYHEADERFILES kccompress.h kccompare.h kcmap.h kcregex.h kcfunctional.h" + MYHEADERFILES="$MYHEADERFILES kcdb.h kcplantdb.h kcprotodb.h kcstashdb.h kccachedb.h" + MYHEADERFILES="$MYHEADERFILES kchashdb.h kcdirdb.h kctextdb.h kcpolydb.h kcdbext.h kclangc.h" + MYLIBRARYFILES="libkyotocabinet.a" +--- kyotocabinet-1.2.76/configure.in 2012-05-24 13:31:42.000000000 +0200 ++++ kyotocabinet-1.2.76/configure.in.tr1_hashtable 2013-11-17 03:12:07.000000000 +0100 +@@ -16,7 +16,7 @@ + + # Targets + MYHEADERFILES="kccommon.h kcutil.h kcthread.h kcfile.h" +-MYHEADERFILES="$MYHEADERFILES kccompress.h kccompare.h kcmap.h kcregex.h" ++MYHEADERFILES="$MYHEADERFILES kccompress.h kccompare.h kcmap.h kcregex.h kcfunctional.h" + MYHEADERFILES="$MYHEADERFILES kcdb.h kcplantdb.h kcprotodb.h kcstashdb.h kccachedb.h" + MYHEADERFILES="$MYHEADERFILES kchashdb.h kcdirdb.h kctextdb.h kcpolydb.h kcdbext.h kclangc.h" + MYLIBRARYFILES="libkyotocabinet.a" +--- kyotocabinet-1.2.76/kccommon.h 2012-05-24 18:27:59.000000000 +0200 ++++ kyotocabinet-1.2.76/kccommon.h.tr1_hashtable 2013-03-01 00:09:59.000000000 +0100 +@@ -44,7 +44,7 @@ + #include + + #include +-#include ++#include + #include + #include + #include +--- kyotocabinet-1.2.76/kcfunctional.h 1970-01-01 01:00:00.000000000 +0100 ++++ kyotocabinet-1.2.76/kcfunctional.h.tr1_hashtable 2013-03-01 00:06:28.000000000 +0100 +@@ -0,0 +1,1282 @@ ++// TR1 functional header -*- C++ -*- ++ ++// Copyright (C) 2004, 2005 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++/** @file ++ * This is a TR1 C++ Library header. ++ */ ++ ++#ifndef _TR1_FUNCTIONAL ++#define _TR1_FUNCTIONAL 1 ++ ++#pragma GCC system_header ++ ++#include "../functional" ++#include ++#include ++#include ++#include // for std::tr1::hash ++#include // for std::abort ++#include // for std::frexp ++#include ++ ++namespace std ++{ ++namespace tr1 ++{ ++ template ++ class _Mem_fn; ++ ++ /** ++ * @if maint ++ * Actual implementation of _Has_result_type, which uses SFINAE to ++ * determine if the type _Tp has a publicly-accessible member type ++ * result_type. ++ * @endif ++ */ ++ template ++ class _Has_result_type_helper : __sfinae_types ++ { ++ template ++ struct _Wrap_type ++ { }; ++ ++ template ++ static __one __test(_Wrap_type*); ++ ++ template ++ static __two __test(...); ++ ++ public: ++ static const bool value = sizeof(__test<_Tp>(0)) == 1; ++ }; ++ ++ template ++ struct _Has_result_type ++ : integral_constant< ++ bool, ++ _Has_result_type_helper::type>::value> ++ { }; ++ ++ /** ++ * @if maint ++ * If we have found a result_type, extract it. ++ * @endif ++ */ ++ template ++ struct _Maybe_get_result_type ++ { }; ++ ++ template ++ struct _Maybe_get_result_type ++ { ++ typedef typename _Functor::result_type result_type; ++ }; ++ ++ /** ++ * @if maint ++ * Base class for any function object that has a weak result type, as ++ * defined in 3.3/3 of TR1. ++ * @endif ++ */ ++ template ++ struct _Weak_result_type_impl ++ : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> ++ { ++ }; ++ ++ /** ++ * @if maint ++ * Strip top-level cv-qualifiers from the function object and let ++ * _Weak_result_type_impl perform the real work. ++ * @endif ++ */ ++ template ++ struct _Weak_result_type ++ : _Weak_result_type_impl::type> ++ { ++ }; ++ ++ template ++ class result_of; ++ ++ /** ++ * @if maint ++ * Actual implementation of result_of. When _Has_result_type is ++ * true, gets its result from _Weak_result_type. Otherwise, uses ++ * the function object's member template result to extract the ++ * result type. ++ * @endif ++ */ ++ template ++ struct _Result_of_impl; ++ ++ // Handle member data pointers using _Mem_fn's logic ++ template ++ struct _Result_of_impl ++ { ++ typedef typename _Mem_fn<_Res _Class::*> ++ ::template _Result_type<_T1>::type type; ++ }; ++ ++ /** ++ * @if maint ++ * Determines if the type _Tp derives from unary_function. ++ * @endif ++ */ ++ template ++ struct _Derives_from_unary_function : __sfinae_types ++ { ++ private: ++ template ++ static __one __test(const volatile unary_function<_T1, _Res>*); ++ ++ // It's tempting to change "..." to const volatile void*, but ++ // that fails when _Tp is a function type. ++ static __two __test(...); ++ ++ public: ++ static const bool value = sizeof(__test((_Tp*)0)) == 1; ++ }; ++ ++ /** ++ * @if maint ++ * Determines if the type _Tp derives from binary_function. ++ * @endif ++ */ ++ template ++ struct _Derives_from_binary_function : __sfinae_types ++ { ++ private: ++ template ++ static __one __test(const volatile binary_function<_T1, _T2, _Res>*); ++ ++ // It's tempting to change "..." to const volatile void*, but ++ // that fails when _Tp is a function type. ++ static __two __test(...); ++ ++ public: ++ static const bool value = sizeof(__test((_Tp*)0)) == 1; ++ }; ++ ++ /** ++ * @if maint ++ * Turns a function type into a function pointer type ++ * @endif ++ */ ++ template::value> ++ struct _Function_to_function_pointer ++ { ++ typedef _Tp type; ++ }; ++ ++ template ++ struct _Function_to_function_pointer<_Tp, true> ++ { ++ typedef _Tp* type; ++ }; ++ ++ /** ++ * @if maint ++ * Knowing which of unary_function and binary_function _Tp derives ++ * from, derives from the same and ensures that reference_wrapper ++ * will have a weak result type. See cases below. ++ * @endif ++ */ ++ template ++ struct _Reference_wrapper_base_impl; ++ ++ // Not a unary_function or binary_function, so try a weak result type ++ template ++ struct _Reference_wrapper_base_impl ++ : _Weak_result_type<_Tp> ++ { }; ++ ++ // unary_function but not binary_function ++ template ++ struct _Reference_wrapper_base_impl ++ : unary_function ++ { }; ++ ++ // binary_function but not unary_function ++ template ++ struct _Reference_wrapper_base_impl ++ : binary_function ++ { }; ++ ++ // both unary_function and binary_function. import result_type to ++ // avoid conflicts. ++ template ++ struct _Reference_wrapper_base_impl ++ : unary_function, ++ binary_function ++ { ++ typedef typename _Tp::result_type result_type; ++ }; ++ ++ /** ++ * @if maint ++ * Derives from unary_function or binary_function when it ++ * can. Specializations handle all of the easy cases. The primary ++ * template determines what to do with a class type, which may ++ * derive from both unary_function and binary_function. ++ * @endif ++ */ ++ template ++ struct _Reference_wrapper_base ++ : _Reference_wrapper_base_impl< ++ _Derives_from_unary_function<_Tp>::value, ++ _Derives_from_binary_function<_Tp>::value, ++ _Tp> ++ { }; ++ ++ // - a function type (unary) ++ template ++ struct _Reference_wrapper_base<_Res(_T1)> ++ : unary_function<_T1, _Res> ++ { }; ++ ++ // - a function type (binary) ++ template ++ struct _Reference_wrapper_base<_Res(_T1, _T2)> ++ : binary_function<_T1, _T2, _Res> ++ { }; ++ ++ // - a function pointer type (unary) ++ template ++ struct _Reference_wrapper_base<_Res(*)(_T1)> ++ : unary_function<_T1, _Res> ++ { }; ++ ++ // - a function pointer type (binary) ++ template ++ struct _Reference_wrapper_base<_Res(*)(_T1, _T2)> ++ : binary_function<_T1, _T2, _Res> ++ { }; ++ ++ // - a pointer to member function type (unary, no qualifiers) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)()> ++ : unary_function<_T1*, _Res> ++ { }; ++ ++ // - a pointer to member function type (binary, no qualifiers) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)(_T2)> ++ : binary_function<_T1*, _T2, _Res> ++ { }; ++ ++ // - a pointer to member function type (unary, const) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)() const> ++ : unary_function ++ { }; ++ ++ // - a pointer to member function type (binary, const) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const> ++ : binary_function ++ { }; ++ ++ // - a pointer to member function type (unary, volatile) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)() volatile> ++ : unary_function ++ { }; ++ ++ // - a pointer to member function type (binary, volatile) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile> ++ : binary_function ++ { }; ++ ++ // - a pointer to member function type (unary, const volatile) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)() const volatile> ++ : unary_function ++ { }; ++ ++ // - a pointer to member function type (binary, const volatile) ++ template ++ struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile> ++ : binary_function ++ { }; ++ ++ template ++ class reference_wrapper ++ : public _Reference_wrapper_base::type> ++ { ++ // If _Tp is a function type, we can't form result_of<_Tp(...)>, ++ // so turn it into a function pointer type. ++ typedef typename _Function_to_function_pointer<_Tp>::type ++ _M_func_type; ++ ++ _Tp* _M_data; ++ public: ++ typedef _Tp type; ++ explicit reference_wrapper(_Tp& __indata): _M_data(&__indata) ++ { } ++ ++ reference_wrapper(const reference_wrapper<_Tp>& __inref): ++ _M_data(__inref._M_data) ++ { } ++ ++ reference_wrapper& ++ operator=(const reference_wrapper<_Tp>& __inref) ++ { ++ _M_data = __inref._M_data; ++ return *this; ++ } ++ ++ operator _Tp&() const ++ { return this->get(); } ++ ++ _Tp& ++ get() const ++ { return *_M_data; } ++ ++#define _GLIBCXX_REPEAT_HEADER ++#include ++#undef _GLIBCXX_REPEAT_HEADER ++ }; ++ ++ ++ // Denotes a reference should be taken to a variable. ++ template ++ inline reference_wrapper<_Tp> ++ ref(_Tp& __t) ++ { return reference_wrapper<_Tp>(__t); } ++ ++ // Denotes a const reference should be taken to a variable. ++ template ++ inline reference_wrapper ++ cref(const _Tp& __t) ++ { return reference_wrapper(__t); } ++ ++ template ++ inline reference_wrapper<_Tp> ++ ref(reference_wrapper<_Tp> __t) ++ { return ref(__t.get()); } ++ ++ template ++ inline reference_wrapper ++ cref(reference_wrapper<_Tp> __t) ++ { return cref(__t.get()); } ++ ++ template ++ struct _Mem_fn_const_or_non ++ { ++ typedef const _Tp& type; ++ }; ++ ++ template ++ struct _Mem_fn_const_or_non<_Tp, false> ++ { ++ typedef _Tp& type; ++ }; ++ ++ template ++ class _Mem_fn<_Res _Class::*> ++ { ++ // This bit of genius is due to Peter Dimov, improved slightly by ++ // Douglas Gregor. ++ template ++ _Res& ++ _M_call(_Tp& __object, _Class *) const ++ { return __object.*__pm; } ++ ++ template ++ _Res& ++ _M_call(_Tp& __object, _Up * const *) const ++ { return (*__object).*__pm; } ++ ++ template ++ const _Res& ++ _M_call(_Tp& __object, const _Up * const *) const ++ { return (*__object).*__pm; } ++ ++ template ++ const _Res& ++ _M_call(_Tp& __object, const _Class *) const ++ { return __object.*__pm; } ++ ++ template ++ const _Res& ++ _M_call(_Tp& __ptr, const volatile void*) const ++ { return (*__ptr).*__pm; } ++ ++ template static _Tp& __get_ref(); ++ ++ template ++ static __sfinae_types::__one __check_const(_Tp&, _Class*); ++ template ++ static __sfinae_types::__one __check_const(_Tp&, _Up * const *); ++ template ++ static __sfinae_types::__two __check_const(_Tp&, const _Up * const *); ++ template ++ static __sfinae_types::__two __check_const(_Tp&, const _Class*); ++ template ++ static __sfinae_types::__two __check_const(_Tp&, const volatile void*); ++ ++ public: ++ template ++ struct _Result_type ++ : _Mem_fn_const_or_non< ++ _Res, ++ (sizeof(__sfinae_types::__two) ++ == sizeof(__check_const<_Tp>(__get_ref<_Tp>(), (_Tp*)0)))> ++ { }; ++ ++ template ++ struct result; ++ ++ template ++ struct result<_CVMem(_Tp)> ++ : public _Result_type<_Tp> { }; ++ ++ template ++ struct result<_CVMem(_Tp&)> ++ : public _Result_type<_Tp> { }; ++ ++ explicit _Mem_fn(_Res _Class::*__pm) : __pm(__pm) { } ++ ++ // Handle objects ++ _Res& operator()(_Class& __object) const ++ { return __object.*__pm; } ++ ++ const _Res& operator()(const _Class& __object) const ++ { return __object.*__pm; } ++ ++ // Handle pointers ++ _Res& operator()(_Class* __object) const ++ { return __object->*__pm; } ++ ++ const _Res& ++ operator()(const _Class* __object) const ++ { return __object->*__pm; } ++ ++ // Handle smart pointers and derived ++ template ++ typename _Result_type<_Tp>::type ++ operator()(_Tp& __unknown) const ++ { return _M_call(__unknown, &__unknown); } ++ ++ private: ++ _Res _Class::*__pm; ++ }; ++ ++ /** ++ * @brief Returns a function object that forwards to the member ++ * pointer @a pm. ++ */ ++ template ++ inline _Mem_fn<_Tp _Class::*> ++ mem_fn(_Tp _Class::* __pm) ++ { ++ return _Mem_fn<_Tp _Class::*>(__pm); ++ } ++ ++ /** ++ * @brief Determines if the given type _Tp is a function object ++ * should be treated as a subexpression when evaluating calls to ++ * function objects returned by bind(). [TR1 3.6.1] ++ */ ++ template ++ struct is_bind_expression ++ { ++ static const bool value = false; ++ }; ++ ++ /** ++ * @brief Determines if the given type _Tp is a placeholder in a ++ * bind() expression and, if so, which placeholder it is. [TR1 3.6.2] ++ */ ++ template ++ struct is_placeholder ++ { ++ static const int value = 0; ++ }; ++ ++ /** ++ * @if maint ++ * The type of placeholder objects defined by libstdc++. ++ * @endif ++ */ ++ template struct _Placeholder { }; ++ ++ /** ++ * @if maint ++ * Partial specialization of is_placeholder that provides the placeholder ++ * number for the placeholder objects defined by libstdc++. ++ * @endif ++ */ ++ template ++ struct is_placeholder<_Placeholder<_Num> > ++ { ++ static const int value = _Num; ++ }; ++ ++ /** ++ * @if maint ++ * Maps an argument to bind() into an actual argument to the bound ++ * function object [TR1 3.6.3/5]. Only the first parameter should ++ * be specified: the rest are used to determine among the various ++ * implementations. Note that, although this class is a function ++ * object, isn't not entirely normal because it takes only two ++ * parameters regardless of the number of parameters passed to the ++ * bind expression. The first parameter is the bound argument and ++ * the second parameter is a tuple containing references to the ++ * rest of the arguments. ++ * @endif ++ */ ++ template::value, ++ bool _IsPlaceholder = (is_placeholder<_Arg>::value > 0)> ++ class _Mu; ++ ++ /** ++ * @if maint ++ * If the argument is reference_wrapper<_Tp>, returns the ++ * underlying reference. [TR1 3.6.3/5 bullet 1] ++ * @endif ++ */ ++ template ++ class _Mu, false, false> ++ { ++ public: ++ typedef _Tp& result_type; ++ ++ /* Note: This won't actually work for const volatile ++ * reference_wrappers, because reference_wrapper::get() is const ++ * but not volatile-qualified. This might be a defect in the TR. ++ */ ++ template ++ result_type ++ operator()(_CVRef& __arg, const _Tuple&) const volatile ++ { return __arg.get(); } ++ }; ++ ++ /** ++ * @if maint ++ * If the argument is a bind expression, we invoke the underlying ++ * function object with the same cv-qualifiers as we are given and ++ * pass along all of our arguments (unwrapped). [TR1 3.6.3/5 bullet 2] ++ * @endif ++ */ ++ template ++ class _Mu<_Arg, true, false> ++ { ++ public: ++ template class result; ++ ++#define _GLIBCXX_REPEAT_HEADER ++# include ++#undef _GLIBCXX_REPEAT_HEADER ++ }; ++ ++ /** ++ * @if maint ++ * If the argument is a placeholder for the Nth argument, returns ++ * a reference to the Nth argument to the bind function object. ++ * [TR1 3.6.3/5 bullet 3] ++ * @endif ++ */ ++ template ++ class _Mu<_Arg, false, true> ++ { ++ public: ++ template class result; ++ ++ template ++ class result<_CVMu(_CVArg, _Tuple)> ++ { ++ // Add a reference, if it hasn't already been done for us. ++ // This allows us to be a little bit sloppy in constructing ++ // the tuple that we pass to result_of<...>. ++ typedef typename tuple_element<(is_placeholder<_Arg>::value - 1), ++ _Tuple>::type __base_type; ++ ++ public: ++ typedef typename add_reference<__base_type>::type type; ++ }; ++ ++ template ++ typename result<_Mu(_Arg, _Tuple)>::type ++ operator()(const volatile _Arg&, const _Tuple& __tuple) const volatile ++ { ++ return ::std::tr1::get<(is_placeholder<_Arg>::value - 1)>(__tuple); ++ } ++ }; ++ ++ /** ++ * @if maint ++ * If the argument is just a value, returns a reference to that ++ * value. The cv-qualifiers on the reference are the same as the ++ * cv-qualifiers on the _Mu object. [TR1 3.6.3/5 bullet 4] ++ * @endif ++ */ ++ template ++ class _Mu<_Arg, false, false> ++ { ++ public: ++ template struct result; ++ ++ template ++ struct result<_CVMu(_CVArg, _Tuple)> ++ { ++ typedef typename add_reference<_CVArg>::type type; ++ }; ++ ++ // Pick up the cv-qualifiers of the argument ++ template ++ _CVArg& operator()(_CVArg& __arg, const _Tuple&) const volatile ++ { return __arg; } ++ }; ++ ++ /** ++ * @if maint ++ * Maps member pointers into instances of _Mem_fn but leaves all ++ * other function objects untouched. Used by tr1::bind(). The ++ * primary template handles the non--member-pointer case. ++ * @endif ++ */ ++ template ++ struct _Maybe_wrap_member_pointer ++ { ++ typedef _Tp type; ++ static const _Tp& __do_wrap(const _Tp& __x) { return __x; } ++ }; ++ ++ /** ++ * @if maint ++ * Maps member pointers into instances of _Mem_fn but leaves all ++ * other function objects untouched. Used by tr1::bind(). This ++ * partial specialization handles the member pointer case. ++ * @endif ++ */ ++ template ++ struct _Maybe_wrap_member_pointer<_Tp _Class::*> ++ { ++ typedef _Mem_fn<_Tp _Class::*> type; ++ static type __do_wrap(_Tp _Class::* __pm) { return type(__pm); } ++ }; ++ ++ /** ++ * @if maint ++ * Type of the function object returned from bind(). ++ * @endif ++ */ ++ template ++ struct _Bind; ++ ++ /** ++ * @if maint ++ * Type of the function object returned from bind(). ++ * @endif ++ */ ++ template ++ struct _Bind_result; ++ ++ /** ++ * @if maint ++ * Class template _Bind is always a bind expression. ++ * @endif ++ */ ++ template ++ struct is_bind_expression<_Bind<_Signature> > ++ { ++ static const bool value = true; ++ }; ++ ++ /** ++ * @if maint ++ * Class template _Bind_result is always a bind expression. ++ * @endif ++ */ ++ template ++ struct is_bind_expression<_Bind_result<_Result, _Signature> > ++ { ++ static const bool value = true; ++ }; ++ ++ /** ++ * @brief Exception class thrown when class template function's ++ * operator() is called with an empty target. ++ * ++ */ ++ class bad_function_call : public std::exception { }; ++ ++ /** ++ * @if maint ++ * The integral constant expression 0 can be converted into a ++ * pointer to this type. It is used by the function template to ++ * accept NULL pointers. ++ * @endif ++ */ ++ struct _M_clear_type; ++ ++ /** ++ * @if maint ++ * Trait identifying "location-invariant" types, meaning that the ++ * address of the object (or any of its members) will not escape. ++ * Also implies a trivial copy constructor and assignment operator. ++ * @endif ++ */ ++ template ++ struct __is_location_invariant ++ : integral_constant::value ++ || is_member_pointer<_Tp>::value)> ++ { ++ }; ++ ++ class _Undefined_class; ++ ++ union _Nocopy_types ++ { ++ void* _M_object; ++ const void* _M_const_object; ++ void (*_M_function_pointer)(); ++ void (_Undefined_class::*_M_member_pointer)(); ++ }; ++ ++ union _Any_data { ++ void* _M_access() { return &_M_pod_data[0]; } ++ const void* _M_access() const { return &_M_pod_data[0]; } ++ ++ template _Tp& _M_access() ++ { return *static_cast<_Tp*>(_M_access()); } ++ ++ template const _Tp& _M_access() const ++ { return *static_cast(_M_access()); } ++ ++ _Nocopy_types _M_unused; ++ char _M_pod_data[sizeof(_Nocopy_types)]; ++ }; ++ ++ enum _Manager_operation ++ { ++ __get_type_info, ++ __get_functor_ptr, ++ __clone_functor, ++ __destroy_functor ++ }; ++ ++ /* Simple type wrapper that helps avoid annoying const problems ++ when casting between void pointers and pointers-to-pointers. */ ++ template ++ struct _Simple_type_wrapper ++ { ++ _Simple_type_wrapper(_Tp __value) : __value(__value) { } ++ ++ _Tp __value; ++ }; ++ ++ template ++ struct __is_location_invariant<_Simple_type_wrapper<_Tp> > ++ : __is_location_invariant<_Tp> ++ { ++ }; ++ ++ // Converts a reference to a function object into a callable ++ // function object. ++ template ++ inline _Functor& __callable_functor(_Functor& __f) { return __f; } ++ ++ template ++ inline _Mem_fn<_Member _Class::*> ++ __callable_functor(_Member _Class::* &__p) ++ { return mem_fn(__p); } ++ ++ template ++ inline _Mem_fn<_Member _Class::*> ++ __callable_functor(_Member _Class::* const &__p) ++ { return mem_fn(__p); } ++ ++ template ++ class _Function_handler; ++ ++ template ++ class function; ++ ++ ++ /** ++ * @if maint ++ * Base class of all polymorphic function object wrappers. ++ * @endif ++ */ ++ class _Function_base ++ { ++ public: ++ static const std::size_t _M_max_size = sizeof(_Nocopy_types); ++ static const std::size_t _M_max_align = __alignof__(_Nocopy_types); ++ ++ template ++ class _Base_manager ++ { ++ protected: ++ static const bool __stored_locally = ++ (__is_location_invariant<_Functor>::value ++ && sizeof(_Functor) <= _M_max_size ++ && __alignof__(_Functor) <= _M_max_align ++ && (_M_max_align % __alignof__(_Functor) == 0)); ++ typedef integral_constant _Local_storage; ++ ++ // Retrieve a pointer to the function object ++ static _Functor* _M_get_pointer(const _Any_data& __source) ++ { ++ const _Functor* __ptr = ++ __stored_locally? &__source._M_access<_Functor>() ++ /* have stored a pointer */ : __source._M_access<_Functor*>(); ++ return const_cast<_Functor*>(__ptr); ++ } ++ ++ // Clone a location-invariant function object that fits within ++ // an _Any_data structure. ++ static void ++ _M_clone(_Any_data& __dest, const _Any_data& __source, true_type) ++ { ++ new (__dest._M_access()) _Functor(__source._M_access<_Functor>()); ++ } ++ ++ // Clone a function object that is not location-invariant or ++ // that cannot fit into an _Any_data structure. ++ static void ++ _M_clone(_Any_data& __dest, const _Any_data& __source, false_type) ++ { ++ __dest._M_access<_Functor*>() = ++ new _Functor(*__source._M_access<_Functor*>()); ++ } ++ ++ // Destroying a location-invariant object may still require ++ // destruction. ++ static void ++ _M_destroy(_Any_data& __victim, true_type) ++ { ++ __victim._M_access<_Functor>().~_Functor(); ++ } ++ ++ // Destroying an object located on the heap. ++ static void ++ _M_destroy(_Any_data& __victim, false_type) ++ { ++ delete __victim._M_access<_Functor*>(); ++ } ++ ++ public: ++ static bool ++ _M_manager(_Any_data& __dest, const _Any_data& __source, ++ _Manager_operation __op) ++ { ++ switch (__op) { ++ case __get_type_info: ++ __dest._M_access() = &typeid(_Functor); ++ break; ++ ++ case __get_functor_ptr: ++ __dest._M_access<_Functor*>() = _M_get_pointer(__source); ++ break; ++ ++ case __clone_functor: ++ _M_clone(__dest, __source, _Local_storage()); ++ break; ++ ++ case __destroy_functor: ++ _M_destroy(__dest, _Local_storage()); ++ break; ++ } ++ return false; ++ } ++ ++ static void ++ _M_init_functor(_Any_data& __functor, const _Functor& __f) ++ { ++ _M_init_functor(__functor, __f, _Local_storage()); ++ } ++ ++ template ++ static bool ++ _M_not_empty_function(const function<_Signature>& __f) ++ { ++ return __f; ++ } ++ ++ template ++ static bool ++ _M_not_empty_function(const _Tp*& __fp) ++ { ++ return __fp; ++ } ++ ++ template ++ static bool ++ _M_not_empty_function(_Tp _Class::* const& __mp) ++ { ++ return __mp; ++ } ++ ++ template ++ static bool ++ _M_not_empty_function(const _Tp&) ++ { ++ return true; ++ } ++ ++ private: ++ static void ++ _M_init_functor(_Any_data& __functor, const _Functor& __f, true_type) ++ { ++ new (__functor._M_access()) _Functor(__f); ++ } ++ ++ static void ++ _M_init_functor(_Any_data& __functor, const _Functor& __f, false_type) ++ { ++ __functor._M_access<_Functor*>() = new _Functor(__f); ++ } ++ }; ++ ++ template ++ class _Ref_manager : public _Base_manager<_Functor*> ++ { ++ typedef _Function_base::_Base_manager<_Functor*> _Base; ++ ++ public: ++ static bool ++ _M_manager(_Any_data& __dest, const _Any_data& __source, ++ _Manager_operation __op) ++ { ++ switch (__op) { ++ case __get_type_info: ++ __dest._M_access() = &typeid(_Functor); ++ break; ++ ++ case __get_functor_ptr: ++ __dest._M_access<_Functor*>() = *_Base::_M_get_pointer(__source); ++ return is_const<_Functor>::value; ++ break; ++ ++ default: ++ _Base::_M_manager(__dest, __source, __op); ++ } ++ return false; ++ } ++ ++ static void ++ _M_init_functor(_Any_data& __functor, reference_wrapper<_Functor> __f) ++ { ++ // TBD: Use address_of function instead ++ _Base::_M_init_functor(__functor, &__f.get()); ++ } ++ }; ++ ++ _Function_base() : _M_manager(0) { } ++ ++ ~_Function_base() ++ { ++ if (_M_manager) ++ { ++ _M_manager(_M_functor, _M_functor, __destroy_functor); ++ } ++ } ++ ++ ++ bool _M_empty() const { return !_M_manager; } ++ ++ typedef bool (*_Manager_type)(_Any_data&, const _Any_data&, ++ _Manager_operation); ++ ++ _Any_data _M_functor; ++ _Manager_type _M_manager; ++ }; ++ ++ // [3.7.2.7] null pointer comparisons ++ ++ /** ++ * @brief Compares a polymorphic function object wrapper against 0 ++ * (the NULL pointer). ++ * @returns @c true if the wrapper has no target, @c false otherwise ++ * ++ * This function will not throw an exception. ++ */ ++ template ++ inline bool ++ operator==(const function<_Signature>& __f, _M_clear_type*) ++ { ++ return !__f; ++ } ++ ++ /** ++ * @overload ++ */ ++ template ++ inline bool ++ operator==(_M_clear_type*, const function<_Signature>& __f) ++ { ++ return !__f; ++ } ++ ++ /** ++ * @brief Compares a polymorphic function object wrapper against 0 ++ * (the NULL pointer). ++ * @returns @c false if the wrapper has no target, @c true otherwise ++ * ++ * This function will not throw an exception. ++ */ ++ template ++ inline bool ++ operator!=(const function<_Signature>& __f, _M_clear_type*) ++ { ++ return __f; ++ } ++ ++ /** ++ * @overload ++ */ ++ template ++ inline bool ++ operator!=(_M_clear_type*, const function<_Signature>& __f) ++ { ++ return __f; ++ } ++ ++ // [3.7.2.8] specialized algorithms ++ ++ /** ++ * @brief Swap the targets of two polymorphic function object wrappers. ++ * ++ * This function will not throw an exception. ++ */ ++ template ++ inline void ++ swap(function<_Signature>& __x, function<_Signature>& __y) ++ { ++ __x.swap(__y); ++ } ++ ++#define _GLIBCXX_JOIN(X,Y) _GLIBCXX_JOIN2( X , Y ) ++#define _GLIBCXX_JOIN2(X,Y) _GLIBCXX_JOIN3(X,Y) ++#define _GLIBCXX_JOIN3(X,Y) X##Y ++#define _GLIBCXX_REPEAT_HEADER ++#include ++#undef _GLIBCXX_REPEAT_HEADER ++#undef _GLIBCXX_JOIN3 ++#undef _GLIBCXX_JOIN2 ++#undef _GLIBCXX_JOIN ++ ++ // Definition of default hash function std::tr1::hash<>. The types for ++ // which std::tr1::hash is defined is in clause 6.3.3. of the PDTR. ++ template ++ struct hash; ++ ++#define tr1_hashtable_define_trivial_hash(T) \ ++ template<> \ ++ struct hash \ ++ : public std::unary_function \ ++ { \ ++ std::size_t \ ++ operator()(T val) const \ ++ { return static_cast(val); } \ ++ } ++ ++ tr1_hashtable_define_trivial_hash(bool); ++ tr1_hashtable_define_trivial_hash(char); ++ tr1_hashtable_define_trivial_hash(signed char); ++ tr1_hashtable_define_trivial_hash(unsigned char); ++ tr1_hashtable_define_trivial_hash(wchar_t); ++ tr1_hashtable_define_trivial_hash(short); ++ tr1_hashtable_define_trivial_hash(int); ++ tr1_hashtable_define_trivial_hash(long); ++ tr1_hashtable_define_trivial_hash(unsigned short); ++ tr1_hashtable_define_trivial_hash(unsigned int); ++ tr1_hashtable_define_trivial_hash(unsigned long); ++ tr1_hashtable_define_trivial_hash(long long); ++ tr1_hashtable_define_trivial_hash(unsigned long long); ++ ++#undef tr1_hashtable_define_trivial_hash ++ ++ template ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(T* p) const ++ { return reinterpret_cast(p); } ++ }; ++ ++ // Fowler / Noll / Vo (FNV) Hash (type FNV-1a) ++ // (used by the next specializations of std::tr1::hash<>) ++ ++ // Dummy generic implementation (for sizeof(size_t) != 4, 8). ++ template ++ struct Fnv_hash ++ { ++ static std::size_t ++ hash(const char* first, std::size_t length) ++ { ++ std::size_t result = 0; ++ for (; length > 0; --length) ++ result = (result * 131) + *first++; ++ return result; ++ } ++ }; ++ ++ template<> ++ struct Fnv_hash<4> ++ { ++ static std::size_t ++ hash(const char* first, std::size_t length) ++ { ++ std::size_t result = static_cast(2166136261UL); ++ for (; length > 0; --length) ++ { ++ result ^= (std::size_t)*first++; ++ result *= 16777619UL; ++ } ++ return result; ++ } ++ }; ++ ++ template<> ++ struct Fnv_hash<8> ++ { ++ static std::size_t ++ hash(const char* first, std::size_t length) ++ { ++ std::size_t result = static_cast(14695981039346656037ULL); ++ for (; length > 0; --length) ++ { ++ result ^= (std::size_t)*first++; ++ result *= 1099511628211ULL; ++ } ++ return result; ++ } ++ }; ++ ++ // XXX String and floating point hashes probably shouldn't be inline ++ // member functions, since are nontrivial. Once we have the framework ++ // for TR1 .cc files, these should go in one. ++ template<> ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(const std::string& s) const ++ { return Fnv_hash<>::hash(s.data(), s.length()); } ++ }; ++ ++#ifdef _GLIBCXX_USE_WCHAR_T ++ template<> ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(const std::wstring& s) const ++ { ++ return Fnv_hash<>::hash(reinterpret_cast(s.data()), ++ s.length() * sizeof(wchar_t)); ++ } ++ }; ++#endif ++ ++ template<> ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(float fval) const ++ { ++ std::size_t result = 0; ++ ++ // 0 and -0 both hash to zero. ++ if (fval != 0.0f) ++ result = Fnv_hash<>::hash(reinterpret_cast(&fval), ++ sizeof(fval)); ++ return result; ++ } ++ }; ++ ++ template<> ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(double dval) const ++ { ++ std::size_t result = 0; ++ ++ // 0 and -0 both hash to zero. ++ if (dval != 0.0) ++ result = Fnv_hash<>::hash(reinterpret_cast(&dval), ++ sizeof(dval)); ++ return result; ++ } ++ }; ++ ++ // For long double, careful with random padding bits (e.g., on x86, ++ // 10 bytes -> 12 bytes) and resort to frexp. ++ template<> ++ struct hash ++ : public std::unary_function ++ { ++ std::size_t ++ operator()(long double ldval) const ++ { ++ std::size_t result = 0; ++ ++ int exponent; ++ ldval = std::frexp(ldval, &exponent); ++ ldval = ldval < 0.0l ? -(ldval + 0.5l) : ldval; ++ ++ const long double mult = std::numeric_limits::max() + 1.0l; ++ ldval *= mult; ++ ++ // Try to use all the bits of the mantissa (really necessary only ++ // on 32-bit targets, at least for 80-bit floating point formats). ++ const std::size_t hibits = (std::size_t)ldval; ++ ldval = (ldval - (long double)hibits) * mult; ++ ++ const std::size_t coeff = ++ (std::numeric_limits::max() ++ / std::numeric_limits::max_exponent); ++ ++ result = hibits + (std::size_t)ldval + coeff * exponent; ++ ++ return result; ++ } ++ }; ++} ++} ++ ++#endif diff --git a/SPECS/kyotocabinet.spec b/SPECS/kyotocabinet.spec new file mode 100644 index 0000000..353687a --- /dev/null +++ b/SPECS/kyotocabinet.spec @@ -0,0 +1,264 @@ +Summary: A straightforward implementation of DBM +Name: kyotocabinet +Version: 1.2.76 +Release: 17%{?dist} +License: GPLv3 +Group: Applications/Databases +URL: http://fallabs.com/%{name}/ +Source: http://fallabs.com/%{name}/pkg/%{name}-%{version}.tar.gz +Patch0: kyotocabinet-1.2.76-cflags.patch +Patch1: kyotocabinet-1.2.76-8-byte-atomics.patch +Patch2: kyotocabinet-1.2.76-tr1_hashtable.patch +Patch3: kyotocabinet-1.2.76-gcc6.patch +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +BuildRequires: zlib-devel, lzo-devel, xz-devel + +%description +Kyoto Cabinet is a library of routines for managing a database. The +database is a simple data file containing records, each is a pair of +a key and a value. Every key and value is serial bytes with variable +length. Both binary data and character string can be used as a key +and a value. Each key must be unique within a database. And there is +neither concept of data tables nor data types. Records are organized +in hash table or B+ tree. + +%package libs +Summary: Libraries for applications using Kyoto Cabinet +Group: System Environment/Libraries +Provides: %{name}-lib = %{version}-%{release} +Provides: %{name}-lib%{?_isa} = %{version}-%{release} +Obsoletes: %{name}-lib < 1.2.76-3 + +%description libs +The kyotocabinet-libs package provides the essential shared libraries +for any Kyoto Cabinet client program or interface. + +%package devel +Summary: Development files for Kyoto Cabinet +Group: Development/Libraries +Requires: %{name}-libs%{?_isa} = %{version}-%{release}, pkgconfig + +%description devel +The kyotocabinet-devel package contains libraries and header files for +developing applications that use Kyoto Cabinet. + +%package apidocs +Summary: API documentation for Kyoto Cabinet library +Group: Documentation +%if 0%{?fedora}%{?rhel} >= 6 +BuildArch: noarch +%endif +Provides: %{name}-api-doc = %{version}-%{release} +Obsoletes: %{name}-api-doc < 1.2.76-3 + +%description apidocs +The kyotocabinet-apidocs package contains API documentation for developing +applications that use Kyoto Cabinet. + +%prep +%setup -q +%patch0 -p1 -b .cflags +%patch1 -p1 -b .8-byte-atomics +%if 0%{?rhel} == 5 +%patch2 -p1 -b .tr1_hashtable +%endif +%patch3 -p1 -b .gcc6 + +%build +%configure --disable-opt --enable-lzo --enable-lzma +make %{?_smp_mflags} + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT INSTALL='install -p' install + +# Don't install any static .a file +rm -f $RPM_BUILD_ROOT%{_libdir}/libkyotocabinet.a + +# Clean up for later usage in documentation +rm -rf $RPM_BUILD_ROOT%{_defaultdocdir} + +%check +# All kcutilmgr compression tests on RHEL 5 (ppc) just cause 99.9% CPU +# usage but do not continue or simply fail. However all the other tests +# including compression ones work as expected. What is the impact here? +%if 0%{?rhel} == 5 && "%{_arch}" == "ppc" +sed -e '/$(RUNENV) $(RUNCMD) .\/kcutilmgr comp /d' -i Makefile +%endif +make check + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +%doc doc/{command.html,common.css,icon16.png} +%{_bindir}/kccachetest +%{_bindir}/kcdirmgr +%{_bindir}/kcdirtest +%{_bindir}/kcforestmgr +%{_bindir}/kcforesttest +%{_bindir}/kcgrasstest +%{_bindir}/kchashmgr +%{_bindir}/kchashtest +%{_bindir}/kclangctest +%{_bindir}/kcpolymgr +%{_bindir}/kcpolytest +%{_bindir}/kcprototest +%{_bindir}/kcstashtest +%{_bindir}/kctreemgr +%{_bindir}/kctreetest +%{_bindir}/kcutilmgr +%{_bindir}/kcutiltest +%{_mandir}/man1/kccachetest.1* +%{_mandir}/man1/kcdirmgr.1* +%{_mandir}/man1/kcdirtest.1* +%{_mandir}/man1/kcforestmgr.1* +%{_mandir}/man1/kcforesttest.1* +%{_mandir}/man1/kcgrasstest.1* +%{_mandir}/man1/kchashmgr.1* +%{_mandir}/man1/kchashtest.1* +%{_mandir}/man1/kclangctest.1* +%{_mandir}/man1/kcpolymgr.1* +%{_mandir}/man1/kcpolytest.1* +%{_mandir}/man1/kcprototest.1* +%{_mandir}/man1/kcstashtest.1* +%{_mandir}/man1/kctreemgr.1* +%{_mandir}/man1/kctreetest.1* +%{_mandir}/man1/kcutilmgr.1* +%{_mandir}/man1/kcutiltest.1* + +%files libs +%defattr(-,root,root,-) +%{!?_licensedir:%global license %%doc} +%license COPYING FOSSEXCEPTION LINKEXCEPTION +%doc ChangeLog +%{_libdir}/libkyotocabinet.so.* + +%files devel +%defattr(-,root,root,-) +%{_includedir}/kccachedb.h +%{_includedir}/kccommon.h +%{_includedir}/kccompare.h +%{_includedir}/kccompress.h +%{_includedir}/kcdb.h +%{_includedir}/kcdbext.h +%{_includedir}/kcdirdb.h +%{_includedir}/kcfile.h +%if 0%{?rhel} == 5 +%{_includedir}/kcfunctional.h +%endif +%{_includedir}/kchashdb.h +%{_includedir}/kclangc.h +%{_includedir}/kcmap.h +%{_includedir}/kcplantdb.h +%{_includedir}/kcpolydb.h +%{_includedir}/kcprotodb.h +%{_includedir}/kcregex.h +%{_includedir}/kcstashdb.h +%{_includedir}/kctextdb.h +%{_includedir}/kcthread.h +%{_includedir}/kcutil.h +%{_libdir}/libkyotocabinet.so +%{_libdir}/pkgconfig/kyotocabinet.pc + +%files apidocs +%defattr(-,root,root,-) +%doc COPYING doc/api/* kyotocabinet.idl + +%changelog +* Wed Mar 07 2018 Adam Williamson - 1.2.76-17 +- Rebuild to fix GCC 8 mis-compilation + See https://da.gd/YJVwk ("GCC 8 ABI change on x86_64") + +* Wed Feb 07 2018 Fedora Release Engineering - 1.2.76-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 1.2.76-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.2.76-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Sun Feb 12 2017 Robert Scheck 1.2.76-13 +- Replace patch from openSUSE by the Debian one to not only build + kyotocabinet with GCC >= 6 but also with GCC >= 7 (#1307706 #c15) + +* Fri Feb 10 2017 Fedora Release Engineering - 1.2.76-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Sun Aug 14 2016 Robert Scheck 1.2.76-11 +- Added patch from openSUSE to build with GCC >= 6 (#1307706) + +* Thu Feb 04 2016 Fedora Release Engineering - 1.2.76-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 1.2.76-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sun May 03 2015 Kalev Lember - 1.2.76-8 +- Rebuilt for GCC 5 C++11 ABI change + +* Sun Aug 17 2014 Fedora Release Engineering - 1.2.76-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 1.2.76-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sun Nov 17 2013 Robert Scheck 1.2.76-5 +- Corrected wrong dependency of -devel from main to -libs package +- Always enable 8 byte atomics patch e.g. for ppc32 (#1007732 #c5) +- Fixed previously added patch for building under RHEL 5 (#915123) +- Added dependencies to enable lzo and lzma/xz compression support +- Enabled the built-in test suite (with limitations at RHEL 5 ppc) + +* Sat Aug 03 2013 Fedora Release Engineering - 1.2.76-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sat Mar 02 2013 Robert Scheck 1.2.76-3 +- Splitted main package into an additional library subpackage +- Added patch and workaround for building under RHEL 5 (#915123) +- Corrected duplicate doc packaging, renamed package to apidocs + +* Thu Feb 14 2013 Fedora Release Engineering - 1.2.76-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Sat Jan 12 2013 Robert Scheck - 1.2.76-1 +- Update to 1.2.76 (#760939) + +* Thu Jul 19 2012 Fedora Release Engineering - 1.2.70-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Feb 28 2012 Fedora Release Engineering - 1.2.70-4 +- Rebuilt for c++ ABI breakage + +* Fri Jan 13 2012 Fedora Release Engineering - 1.2.70-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Oct 19 2011 Casey Dahlin - 1.2.70-2 +- Prevent -march=native build flag [735822], credit Ville Skyatta + + +* Wed Aug 31 2011 Casey Dahlin - 1.2.70-1 +- Update to latest upstream + +* Mon Feb 07 2011 Fedora Release Engineering - 1.2.31-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 3 2011 Casey Dahlin - 1.2.31-2 +- Correct files list for soname bump + +* Mon Jan 3 2011 Casey Dahlin - 1.2.31-1 +- Update to latest upstream + +* Mon Dec 13 2010 Casey Dahlin - 1.2.29-1 +- Update to latest upstream + +* Fri Dec 10 2010 Casey Dahlin - 1.2.27-2 +- Separate out devel-doc package +- Make sure we own our documentation folder +- Kill rpath + +* Wed Dec 8 2010 Casey Dahlin - 1.2.27-1 +- Initial packaging