annotate DEPENDENCIES/generic/include/boost/unordered/detail/util.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1
Chris@16 2 // Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
Chris@16 3 // Copyright (C) 2005-2011 Daniel James
Chris@16 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6
Chris@16 7 #ifndef BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED
Chris@16 8 #define BOOST_UNORDERED_DETAIL_UTIL_HPP_INCLUDED
Chris@16 9
Chris@101 10 #include <boost/config.hpp>
Chris@101 11 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 12 #pragma once
Chris@16 13 #endif
Chris@16 14
Chris@16 15 #include <boost/type_traits/is_convertible.hpp>
Chris@16 16 #include <boost/type_traits/is_empty.hpp>
Chris@16 17 #include <boost/iterator/iterator_categories.hpp>
Chris@16 18 #include <boost/utility/enable_if.hpp>
Chris@16 19 #include <boost/detail/select_type.hpp>
Chris@16 20 #include <boost/move/move.hpp>
Chris@16 21 #include <boost/preprocessor/seq/size.hpp>
Chris@16 22 #include <boost/preprocessor/seq/enum.hpp>
Chris@16 23 #include <boost/swap.hpp>
Chris@16 24
Chris@16 25 namespace boost { namespace unordered { namespace detail {
Chris@16 26
Chris@16 27 static const float minimum_max_load_factor = 1e-3f;
Chris@16 28 static const std::size_t default_bucket_count = 11;
Chris@16 29 struct move_tag {};
Chris@16 30 struct empty_emplace {};
Chris@16 31
Chris@16 32 namespace func {
Chris@16 33 template <class T>
Chris@16 34 inline void ignore_unused_variable_warning(T const&) {}
Chris@16 35 }
Chris@16 36
Chris@16 37 ////////////////////////////////////////////////////////////////////////////
Chris@16 38 // iterator SFINAE
Chris@16 39
Chris@16 40 template <typename I>
Chris@16 41 struct is_forward :
Chris@16 42 boost::is_convertible<
Chris@16 43 typename boost::iterator_traversal<I>::type,
Chris@16 44 boost::forward_traversal_tag>
Chris@16 45 {};
Chris@16 46
Chris@16 47 template <typename I, typename ReturnType>
Chris@16 48 struct enable_if_forward :
Chris@16 49 boost::enable_if_c<
Chris@16 50 boost::unordered::detail::is_forward<I>::value,
Chris@16 51 ReturnType>
Chris@16 52 {};
Chris@16 53
Chris@16 54 template <typename I, typename ReturnType>
Chris@16 55 struct disable_if_forward :
Chris@16 56 boost::disable_if_c<
Chris@16 57 boost::unordered::detail::is_forward<I>::value,
Chris@16 58 ReturnType>
Chris@16 59 {};
Chris@16 60
Chris@16 61 ////////////////////////////////////////////////////////////////////////////
Chris@16 62 // primes
Chris@16 63
Chris@16 64 #define BOOST_UNORDERED_PRIMES \
Chris@16 65 (17ul)(29ul)(37ul)(53ul)(67ul)(79ul) \
Chris@16 66 (97ul)(131ul)(193ul)(257ul)(389ul)(521ul)(769ul) \
Chris@16 67 (1031ul)(1543ul)(2053ul)(3079ul)(6151ul)(12289ul)(24593ul) \
Chris@16 68 (49157ul)(98317ul)(196613ul)(393241ul)(786433ul) \
Chris@16 69 (1572869ul)(3145739ul)(6291469ul)(12582917ul)(25165843ul) \
Chris@16 70 (50331653ul)(100663319ul)(201326611ul)(402653189ul)(805306457ul) \
Chris@16 71 (1610612741ul)(3221225473ul)(4294967291ul)
Chris@16 72
Chris@16 73 template<class T> struct prime_list_template
Chris@16 74 {
Chris@16 75 static std::size_t const value[];
Chris@16 76
Chris@16 77 #if !defined(SUNPRO_CC)
Chris@16 78 static std::ptrdiff_t const length;
Chris@16 79 #else
Chris@16 80 static std::ptrdiff_t const length
Chris@16 81 = BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
Chris@16 82 #endif
Chris@16 83 };
Chris@16 84
Chris@16 85 template<class T>
Chris@16 86 std::size_t const prime_list_template<T>::value[] = {
Chris@16 87 BOOST_PP_SEQ_ENUM(BOOST_UNORDERED_PRIMES)
Chris@16 88 };
Chris@16 89
Chris@16 90 #if !defined(SUNPRO_CC)
Chris@16 91 template<class T>
Chris@16 92 std::ptrdiff_t const prime_list_template<T>::length
Chris@16 93 = BOOST_PP_SEQ_SIZE(BOOST_UNORDERED_PRIMES);
Chris@16 94 #endif
Chris@16 95
Chris@16 96 #undef BOOST_UNORDERED_PRIMES
Chris@16 97
Chris@16 98 typedef prime_list_template<std::size_t> prime_list;
Chris@16 99
Chris@16 100 // no throw
Chris@16 101 inline std::size_t next_prime(std::size_t num) {
Chris@16 102 std::size_t const* const prime_list_begin = prime_list::value;
Chris@16 103 std::size_t const* const prime_list_end = prime_list_begin +
Chris@16 104 prime_list::length;
Chris@16 105 std::size_t const* bound =
Chris@16 106 std::lower_bound(prime_list_begin, prime_list_end, num);
Chris@16 107 if(bound == prime_list_end)
Chris@16 108 bound--;
Chris@16 109 return *bound;
Chris@16 110 }
Chris@16 111
Chris@16 112 // no throw
Chris@16 113 inline std::size_t prev_prime(std::size_t num) {
Chris@16 114 std::size_t const* const prime_list_begin = prime_list::value;
Chris@16 115 std::size_t const* const prime_list_end = prime_list_begin +
Chris@16 116 prime_list::length;
Chris@16 117 std::size_t const* bound =
Chris@16 118 std::upper_bound(prime_list_begin,prime_list_end, num);
Chris@16 119 if(bound != prime_list_begin)
Chris@16 120 bound--;
Chris@16 121 return *bound;
Chris@16 122 }
Chris@16 123
Chris@16 124 ////////////////////////////////////////////////////////////////////////////
Chris@16 125 // insert_size/initial_size
Chris@16 126
Chris@16 127 #if !defined(BOOST_NO_STD_DISTANCE)
Chris@16 128
Chris@16 129 using ::std::distance;
Chris@16 130
Chris@16 131 #else
Chris@16 132
Chris@16 133 template <class ForwardIterator>
Chris@16 134 inline std::size_t distance(ForwardIterator i, ForwardIterator j) {
Chris@16 135 std::size_t x;
Chris@16 136 std::distance(i, j, x);
Chris@16 137 return x;
Chris@16 138 }
Chris@16 139
Chris@16 140 #endif
Chris@16 141
Chris@16 142 template <class I>
Chris@16 143 inline typename
Chris@16 144 boost::unordered::detail::enable_if_forward<I, std::size_t>::type
Chris@16 145 insert_size(I i, I j)
Chris@16 146 {
Chris@16 147 return std::distance(i, j);
Chris@16 148 }
Chris@16 149
Chris@16 150 template <class I>
Chris@16 151 inline typename
Chris@16 152 boost::unordered::detail::disable_if_forward<I, std::size_t>::type
Chris@16 153 insert_size(I, I)
Chris@16 154 {
Chris@16 155 return 1;
Chris@16 156 }
Chris@16 157
Chris@16 158 template <class I>
Chris@16 159 inline std::size_t initial_size(I i, I j,
Chris@16 160 std::size_t num_buckets =
Chris@16 161 boost::unordered::detail::default_bucket_count)
Chris@16 162 {
Chris@16 163 // TODO: Why +1?
Chris@16 164 return (std::max)(
Chris@16 165 boost::unordered::detail::insert_size(i, j) + 1,
Chris@16 166 num_buckets);
Chris@16 167 }
Chris@16 168
Chris@16 169 ////////////////////////////////////////////////////////////////////////////
Chris@16 170 // compressed
Chris@16 171
Chris@16 172 template <typename T, int Index>
Chris@16 173 struct compressed_base : private T
Chris@16 174 {
Chris@16 175 compressed_base(T const& x) : T(x) {}
Chris@16 176 compressed_base(T& x, move_tag) : T(boost::move(x)) {}
Chris@16 177
Chris@16 178 T& get() { return *this; }
Chris@16 179 T const& get() const { return *this; }
Chris@16 180 };
Chris@16 181
Chris@16 182 template <typename T, int Index>
Chris@16 183 struct uncompressed_base
Chris@16 184 {
Chris@16 185 uncompressed_base(T const& x) : value_(x) {}
Chris@16 186 uncompressed_base(T& x, move_tag) : value_(boost::move(x)) {}
Chris@16 187
Chris@16 188 T& get() { return value_; }
Chris@16 189 T const& get() const { return value_; }
Chris@16 190 private:
Chris@16 191 T value_;
Chris@16 192 };
Chris@16 193
Chris@16 194 template <typename T, int Index>
Chris@16 195 struct generate_base
Chris@16 196 : boost::detail::if_true<
Chris@16 197 boost::is_empty<T>::value
Chris@16 198 >:: BOOST_NESTED_TEMPLATE then<
Chris@16 199 boost::unordered::detail::compressed_base<T, Index>,
Chris@16 200 boost::unordered::detail::uncompressed_base<T, Index>
Chris@16 201 >
Chris@16 202 {};
Chris@16 203
Chris@16 204 template <typename T1, typename T2>
Chris@16 205 struct compressed
Chris@16 206 : private boost::unordered::detail::generate_base<T1, 1>::type,
Chris@16 207 private boost::unordered::detail::generate_base<T2, 2>::type
Chris@16 208 {
Chris@16 209 typedef typename generate_base<T1, 1>::type base1;
Chris@16 210 typedef typename generate_base<T2, 2>::type base2;
Chris@16 211
Chris@16 212 typedef T1 first_type;
Chris@16 213 typedef T2 second_type;
Chris@16 214
Chris@16 215 first_type& first() {
Chris@16 216 return static_cast<base1*>(this)->get();
Chris@16 217 }
Chris@16 218
Chris@16 219 first_type const& first() const {
Chris@16 220 return static_cast<base1 const*>(this)->get();
Chris@16 221 }
Chris@16 222
Chris@16 223 second_type& second() {
Chris@16 224 return static_cast<base2*>(this)->get();
Chris@16 225 }
Chris@16 226
Chris@16 227 second_type const& second() const {
Chris@16 228 return static_cast<base2 const*>(this)->get();
Chris@16 229 }
Chris@16 230
Chris@16 231 template <typename First, typename Second>
Chris@16 232 compressed(First const& x1, Second const& x2)
Chris@16 233 : base1(x1), base2(x2) {}
Chris@16 234
Chris@16 235 compressed(compressed const& x)
Chris@16 236 : base1(x.first()), base2(x.second()) {}
Chris@16 237
Chris@16 238 compressed(compressed& x, move_tag m)
Chris@16 239 : base1(x.first(), m), base2(x.second(), m) {}
Chris@16 240
Chris@16 241 void assign(compressed const& x)
Chris@16 242 {
Chris@16 243 first() = x.first();
Chris@16 244 second() = x.second();
Chris@16 245 }
Chris@16 246
Chris@16 247 void move_assign(compressed& x)
Chris@16 248 {
Chris@16 249 first() = boost::move(x.first());
Chris@16 250 second() = boost::move(x.second());
Chris@16 251 }
Chris@16 252
Chris@16 253 void swap(compressed& x)
Chris@16 254 {
Chris@16 255 boost::swap(first(), x.first());
Chris@16 256 boost::swap(second(), x.second());
Chris@16 257 }
Chris@16 258
Chris@16 259 private:
Chris@16 260 // Prevent assignment just to make use of assign or
Chris@16 261 // move_assign explicit.
Chris@16 262 compressed& operator=(compressed const&);
Chris@16 263 };
Chris@16 264 }}}
Chris@16 265
Chris@16 266 #endif