mirror of
https://github.com/shadps4-emu/ext-boost.git
synced 2024-11-26 21:00:21 +00:00
add stuff for compiler user tracking
This commit is contained in:
parent
f2474e1b58
commit
03863258ea
@ -1,4 +1,9 @@
|
||||
add_library(boost INTERFACE)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/align/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/range/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/optional/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/utility/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/tuple/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/libs/iterator/include/)
|
||||
target_include_directories(boost SYSTEM INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(Boost::headers ALIAS boost)
|
1511
boost/container/list.hpp
Normal file
1511
boost/container/list.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1724
boost/container/slist.hpp
Normal file
1724
boost/container/slist.hpp
Normal file
File diff suppressed because it is too large
Load Diff
146
boost/container_hash/detail/hash_integral.hpp
Normal file
146
boost/container_hash/detail/hash_integral.hpp
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2021-2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP
|
||||
#define BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP
|
||||
|
||||
#include <boost/container_hash/detail/hash_mix.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
// libstdc++ doesn't provide support for __int128 in the standard traits
|
||||
|
||||
template<class T> struct is_integral: public std::is_integral<T>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct is_unsigned: public std::is_unsigned<T>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct make_unsigned: public std::make_unsigned<T>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
|
||||
template<> struct is_integral<__int128_t>: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct is_integral<__uint128_t>: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct is_unsigned<__int128_t>: public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct is_unsigned<__uint128_t>: public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct make_unsigned<__int128_t>
|
||||
{
|
||||
typedef __uint128_t type;
|
||||
};
|
||||
|
||||
template<> struct make_unsigned<__uint128_t>
|
||||
{
|
||||
typedef __uint128_t type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<class T,
|
||||
bool bigger_than_size_t = (sizeof(T) > sizeof(std::size_t)),
|
||||
bool is_unsigned = is_unsigned<T>::value,
|
||||
std::size_t size_t_bits = sizeof(std::size_t) * CHAR_BIT,
|
||||
std::size_t type_bits = sizeof(T) * CHAR_BIT>
|
||||
struct hash_integral_impl;
|
||||
|
||||
template<class T, bool is_unsigned, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl<T, false, is_unsigned, size_t_bits, type_bits>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
return static_cast<std::size_t>( v );
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, std::size_t size_t_bits, std::size_t type_bits> struct hash_integral_impl<T, true, false, size_t_bits, type_bits>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
typedef typename make_unsigned<T>::type U;
|
||||
|
||||
if( v >= 0 )
|
||||
{
|
||||
return hash_integral_impl<U>::fn( static_cast<U>( v ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ~hash_integral_impl<U>::fn( static_cast<U>( ~static_cast<U>( v ) ) );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, true, 32, 64>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed = static_cast<std::size_t>( v >> 32 ) + hash_detail::hash_mix( seed );
|
||||
seed = static_cast<std::size_t>( v & 0xFFFFFFFF ) + hash_detail::hash_mix( seed );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, true, 32, 128>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed = static_cast<std::size_t>( v >> 96 ) + hash_detail::hash_mix( seed );
|
||||
seed = static_cast<std::size_t>( v >> 64 ) + hash_detail::hash_mix( seed );
|
||||
seed = static_cast<std::size_t>( v >> 32 ) + hash_detail::hash_mix( seed );
|
||||
seed = static_cast<std::size_t>( v ) + hash_detail::hash_mix( seed );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct hash_integral_impl<T, true, true, 64, 128>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed = static_cast<std::size_t>( v >> 64 ) + hash_detail::hash_mix( seed );
|
||||
seed = static_cast<std::size_t>( v ) + hash_detail::hash_mix( seed );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<hash_detail::is_integral<T>::value, std::size_t>::type
|
||||
hash_value( T v )
|
||||
{
|
||||
return hash_detail::hash_integral_impl<T>::fn( v );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_INTEGRAL_HPP
|
113
boost/container_hash/detail/hash_mix.hpp
Normal file
113
boost/container_hash/detail/hash_mix.hpp
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP
|
||||
#define BOOST_HASH_DETAIL_HASH_MIX_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<std::size_t Bits> struct hash_mix_impl;
|
||||
|
||||
// hash_mix for 64 bit size_t
|
||||
//
|
||||
// The general "xmxmx" form of state of the art 64 bit mixers originates
|
||||
// from Murmur3 by Austin Appleby, which uses the following function as
|
||||
// its "final mix":
|
||||
//
|
||||
// k ^= k >> 33;
|
||||
// k *= 0xff51afd7ed558ccd;
|
||||
// k ^= k >> 33;
|
||||
// k *= 0xc4ceb9fe1a85ec53;
|
||||
// k ^= k >> 33;
|
||||
//
|
||||
// (https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp)
|
||||
//
|
||||
// It has subsequently been improved multiple times by different authors
|
||||
// by changing the constants. The most well known improvement is the
|
||||
// so-called "variant 13" function by David Stafford:
|
||||
//
|
||||
// k ^= k >> 30;
|
||||
// k *= 0xbf58476d1ce4e5b9;
|
||||
// k ^= k >> 27;
|
||||
// k *= 0x94d049bb133111eb;
|
||||
// k ^= k >> 31;
|
||||
//
|
||||
// (https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html)
|
||||
//
|
||||
// This mixing function is used in the splitmix64 RNG:
|
||||
// http://xorshift.di.unimi.it/splitmix64.c
|
||||
//
|
||||
// We use Jon Maiga's implementation from
|
||||
// http://jonkagstrom.com/mx3/mx3_rev2.html
|
||||
//
|
||||
// x ^= x >> 32;
|
||||
// x *= 0xe9846af9b1a615d;
|
||||
// x ^= x >> 32;
|
||||
// x *= 0xe9846af9b1a615d;
|
||||
// x ^= x >> 28;
|
||||
//
|
||||
// An equally good alternative is Pelle Evensen's Moremur:
|
||||
//
|
||||
// x ^= x >> 27;
|
||||
// x *= 0x3C79AC492BA7B653;
|
||||
// x ^= x >> 33;
|
||||
// x *= 0x1C69B3F74AC4AE35;
|
||||
// x ^= x >> 27;
|
||||
//
|
||||
// (https://mostlymangling.blogspot.com/2019/12/stronger-better-morer-moremur-better.html)
|
||||
|
||||
template<> struct hash_mix_impl<64>
|
||||
{
|
||||
inline static std::uint64_t fn( std::uint64_t x )
|
||||
{
|
||||
std::uint64_t const m = 0xe9846af9b1a615d;
|
||||
|
||||
x ^= x >> 32;
|
||||
x *= m;
|
||||
x ^= x >> 32;
|
||||
x *= m;
|
||||
x ^= x >> 28;
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
// hash_mix for 32 bit size_t
|
||||
//
|
||||
// We use the "best xmxmx" implementation from
|
||||
// https://github.com/skeeto/hash-prospector/issues/19
|
||||
|
||||
template<> struct hash_mix_impl<32>
|
||||
{
|
||||
inline static std::uint32_t fn( std::uint32_t x )
|
||||
{
|
||||
std::uint32_t const m1 = 0x21f0aaad;
|
||||
std::uint32_t const m2 = 0x735a2d97;
|
||||
|
||||
x ^= x >> 16;
|
||||
x *= m1;
|
||||
x ^= x >> 15;
|
||||
x *= m2;
|
||||
x ^= x >> 15;
|
||||
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
inline std::size_t hash_mix( std::size_t v )
|
||||
{
|
||||
return hash_mix_impl<sizeof(std::size_t) * CHAR_BIT>::fn( v );
|
||||
}
|
||||
|
||||
} // namespace hash_detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_MIX_HPP
|
408
boost/container_hash/detail/hash_range.hpp
Normal file
408
boost/container_hash/detail/hash_range.hpp
Normal file
@ -0,0 +1,408 @@
|
||||
// Copyright 2022 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP
|
||||
#define BOOST_HASH_DETAIL_HASH_RANGE_HPP
|
||||
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/container_hash/detail/mulx.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <cstddef>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<class T> struct is_char_type: public std::false_type {};
|
||||
|
||||
#if CHAR_BIT == 8
|
||||
|
||||
template<> struct is_char_type<char>: public std::true_type {};
|
||||
template<> struct is_char_type<signed char>: public std::true_type {};
|
||||
template<> struct is_char_type<unsigned char>: public std::true_type {};
|
||||
|
||||
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
||||
template<> struct is_char_type<char8_t>: public std::true_type {};
|
||||
#endif
|
||||
|
||||
#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L
|
||||
template<> struct is_char_type<std::byte>: public std::true_type {};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// generic version
|
||||
|
||||
template<class It>
|
||||
inline typename std::enable_if<
|
||||
!is_char_type<typename std::iterator_traits<It>::value_type>::value,
|
||||
std::size_t >::type
|
||||
hash_range( std::size_t seed, It first, It last )
|
||||
{
|
||||
for( ; first != last; ++first )
|
||||
{
|
||||
hash_combine<typename std::iterator_traits<It>::value_type>( seed, *first );
|
||||
}
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
// specialized char[] version, 32 bit
|
||||
|
||||
template<class It> inline std::uint32_t read32le( It p )
|
||||
{
|
||||
// clang 5+, gcc 5+ figure out this pattern and use a single mov on x86
|
||||
// gcc on s390x and power BE even knows how to use load-reverse
|
||||
|
||||
std::uint32_t w =
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[0] ) ) |
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[1] ) ) << 8 |
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[2] ) ) << 16 |
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[3] ) ) << 24;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
template<class T> inline std::uint32_t read32le( T* p )
|
||||
{
|
||||
std::uint32_t w;
|
||||
|
||||
std::memcpy( &w, p, 4 );
|
||||
return w;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline std::uint64_t mul32( std::uint32_t x, std::uint32_t y )
|
||||
{
|
||||
return static_cast<std::uint64_t>( x ) * y;
|
||||
}
|
||||
|
||||
template<class It>
|
||||
inline typename std::enable_if<
|
||||
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
|
||||
std::is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value &&
|
||||
std::numeric_limits<std::size_t>::digits <= 32,
|
||||
std::size_t>::type
|
||||
hash_range( std::size_t seed, It first, It last )
|
||||
{
|
||||
It p = first;
|
||||
std::size_t n = static_cast<std::size_t>( last - first );
|
||||
|
||||
std::uint32_t const q = 0x9e3779b9U;
|
||||
std::uint32_t const k = 0xe35e67b1U; // q * q
|
||||
|
||||
std::uint64_t h = mul32( static_cast<std::uint32_t>( seed ) + q, k );
|
||||
std::uint32_t w = static_cast<std::uint32_t>( h & 0xFFFFFFFF );
|
||||
|
||||
h ^= n;
|
||||
|
||||
while( n >= 4 )
|
||||
{
|
||||
std::uint32_t v1 = read32le( p );
|
||||
|
||||
w += q;
|
||||
h ^= mul32( v1 + w, k );
|
||||
|
||||
p += 4;
|
||||
n -= 4;
|
||||
}
|
||||
|
||||
{
|
||||
std::uint32_t v1 = 0;
|
||||
|
||||
if( n >= 1 )
|
||||
{
|
||||
std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2
|
||||
std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1
|
||||
|
||||
v1 =
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x1 ) ] ) ) << x1 * 8 |
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x2 ) ] ) ) << x2 * 8 |
|
||||
static_cast<std::uint32_t>( static_cast<unsigned char>( p[ 0 ] ) );
|
||||
}
|
||||
|
||||
w += q;
|
||||
h ^= mul32( v1 + w, k );
|
||||
}
|
||||
|
||||
w += q;
|
||||
h ^= mul32( static_cast<std::uint32_t>( h & 0xFFFFFFFF ) + w, static_cast<std::uint32_t>( h >> 32 ) + w + k );
|
||||
|
||||
return static_cast<std::uint32_t>( h & 0xFFFFFFFF ) ^ static_cast<std::uint32_t>( h >> 32 );
|
||||
}
|
||||
|
||||
template<class It>
|
||||
inline typename std::enable_if<
|
||||
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
|
||||
!std::is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value &&
|
||||
std::numeric_limits<std::size_t>::digits <= 32,
|
||||
std::size_t>::type
|
||||
hash_range( std::size_t seed, It first, It last )
|
||||
{
|
||||
std::size_t n = 0;
|
||||
|
||||
std::uint32_t const q = 0x9e3779b9U;
|
||||
std::uint32_t const k = 0xe35e67b1U; // q * q
|
||||
|
||||
std::uint64_t h = mul32( static_cast<std::uint32_t>( seed ) + q, k );
|
||||
std::uint32_t w = static_cast<std::uint32_t>( h & 0xFFFFFFFF );
|
||||
|
||||
std::uint32_t v1 = 0;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
v1 = 0;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint32_t>( static_cast<unsigned char>( *first ) );
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint32_t>( static_cast<unsigned char>( *first ) ) << 8;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint32_t>( static_cast<unsigned char>( *first ) ) << 16;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint32_t>( static_cast<unsigned char>( *first ) ) << 24;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
w += q;
|
||||
h ^= mul32( v1 + w, k );
|
||||
}
|
||||
|
||||
h ^= n;
|
||||
|
||||
w += q;
|
||||
h ^= mul32( v1 + w, k );
|
||||
|
||||
w += q;
|
||||
h ^= mul32( static_cast<std::uint32_t>( h & 0xFFFFFFFF ) + w, static_cast<std::uint32_t>( h >> 32 ) + w + k );
|
||||
|
||||
return static_cast<std::uint32_t>( h & 0xFFFFFFFF ) ^ static_cast<std::uint32_t>( h >> 32 );
|
||||
}
|
||||
|
||||
// specialized char[] version, 64 bit
|
||||
|
||||
template<class It> inline std::uint64_t read64le( It p )
|
||||
{
|
||||
std::uint64_t w =
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[0] ) ) |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[1] ) ) << 8 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[2] ) ) << 16 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[3] ) ) << 24 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[4] ) ) << 32 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[5] ) ) << 40 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[6] ) ) << 48 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[7] ) ) << 56;
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
|
||||
template<class T> inline std::uint64_t read64le( T* p )
|
||||
{
|
||||
std::uint64_t w;
|
||||
|
||||
std::memcpy( &w, p, 8 );
|
||||
return w;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class It>
|
||||
inline typename std::enable_if<
|
||||
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
|
||||
std::is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value &&
|
||||
(std::numeric_limits<std::size_t>::digits > 32),
|
||||
std::size_t>::type
|
||||
hash_range( std::size_t seed, It first, It last )
|
||||
{
|
||||
It p = first;
|
||||
std::size_t n = static_cast<std::size_t>( last - first );
|
||||
|
||||
std::uint64_t const q = 0x9e3779b97f4a7c15;
|
||||
std::uint64_t const k = 0xdf442d22ce4859b9; // q * q
|
||||
|
||||
std::uint64_t w = mulx( seed + q, k );
|
||||
std::uint64_t h = w ^ n;
|
||||
|
||||
while( n >= 8 )
|
||||
{
|
||||
std::uint64_t v1 = read64le( p );
|
||||
|
||||
w += q;
|
||||
h ^= mulx( v1 + w, k );
|
||||
|
||||
p += 8;
|
||||
n -= 8;
|
||||
}
|
||||
|
||||
{
|
||||
std::uint64_t v1 = 0;
|
||||
|
||||
if( n >= 4 )
|
||||
{
|
||||
v1 = static_cast<std::uint64_t>( read32le( p + static_cast<std::ptrdiff_t>( n - 4 ) ) ) << ( n - 4 ) * 8 | read32le( p );
|
||||
}
|
||||
else if( n >= 1 )
|
||||
{
|
||||
std::size_t const x1 = ( n - 1 ) & 2; // 1: 0, 2: 0, 3: 2
|
||||
std::size_t const x2 = n >> 1; // 1: 0, 2: 1, 3: 1
|
||||
|
||||
v1 =
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x1 ) ] ) ) << x1 * 8 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[ static_cast<std::ptrdiff_t>( x2 ) ] ) ) << x2 * 8 |
|
||||
static_cast<std::uint64_t>( static_cast<unsigned char>( p[ 0 ] ) );
|
||||
}
|
||||
|
||||
w += q;
|
||||
h ^= mulx( v1 + w, k );
|
||||
}
|
||||
|
||||
return mulx( h + w, k );
|
||||
}
|
||||
|
||||
template<class It>
|
||||
inline typename std::enable_if<
|
||||
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
|
||||
!std::is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value &&
|
||||
(std::numeric_limits<std::size_t>::digits > 32),
|
||||
std::size_t>::type
|
||||
hash_range( std::size_t seed, It first, It last )
|
||||
{
|
||||
std::size_t n = 0;
|
||||
|
||||
std::uint64_t const q = 0x9e3779b97f4a7c15;
|
||||
std::uint64_t const k = 0xdf442d22ce4859b9; // q * q
|
||||
|
||||
std::uint64_t w = mulx( seed + q, k );
|
||||
std::uint64_t h = w;
|
||||
|
||||
std::uint64_t v1 = 0;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
v1 = 0;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) );
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 8;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 16;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 24;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 32;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 40;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 48;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
if( first == last )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v1 |= static_cast<std::uint64_t>( static_cast<unsigned char>( *first ) ) << 56;
|
||||
++first;
|
||||
++n;
|
||||
|
||||
w += q;
|
||||
h ^= mulx( v1 + w, k );
|
||||
}
|
||||
|
||||
h ^= n;
|
||||
|
||||
w += q;
|
||||
h ^= mulx( v1 + w, k );
|
||||
|
||||
return mulx( h + w, k );
|
||||
}
|
||||
|
||||
} // namespace hash_detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_HPP
|
62
boost/container_hash/detail/hash_tuple_like.hpp
Normal file
62
boost/container_hash/detail/hash_tuple_like.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Copyright 2021 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
|
||||
#define BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
|
||||
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/container_hash/is_tuple_like.hpp>
|
||||
#include <boost/container_hash/is_range.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
inline
|
||||
typename std::enable_if<(I == std::tuple_size<T>::value), void>::type
|
||||
hash_combine_tuple_like( std::size_t&, T const& )
|
||||
{
|
||||
}
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
inline
|
||||
typename std::enable_if<(I < std::tuple_size<T>::value), void>::type
|
||||
hash_combine_tuple_like( std::size_t& seed, T const& v )
|
||||
{
|
||||
using std::get;
|
||||
boost::hash_combine( seed, get<I>( v ) );
|
||||
|
||||
boost::hash_detail::hash_combine_tuple_like<I + 1>( seed, v );
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::size_t hash_tuple_like( T const& v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
boost::hash_detail::hash_combine_tuple_like<0>( seed, v );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
typename std::enable_if<
|
||||
container_hash::is_tuple_like<T>::value && !container_hash::is_range<T>::value,
|
||||
std::size_t>::type
|
||||
hash_value( T const& v )
|
||||
{
|
||||
return boost::hash_detail::hash_tuple_like( v );
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_DETAIL_HASH_TUPLE_LIKE_HPP
|
79
boost/container_hash/detail/mulx.hpp
Normal file
79
boost/container_hash/detail/mulx.hpp
Normal file
@ -0,0 +1,79 @@
|
||||
// Copyright 2022, 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_DETAIL_MULX_HPP
|
||||
#define BOOST_HASH_DETAIL_MULX_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#if defined(_MSC_VER)
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__)
|
||||
|
||||
__forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
|
||||
{
|
||||
std::uint64_t r2;
|
||||
std::uint64_t r = _umul128( x, y, &r2 );
|
||||
return r ^ r2;
|
||||
}
|
||||
|
||||
#elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__)
|
||||
|
||||
__forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
|
||||
{
|
||||
std::uint64_t r = x * y;
|
||||
std::uint64_t r2 = __umulh( x, y );
|
||||
return r ^ r2;
|
||||
}
|
||||
|
||||
#elif defined(__SIZEOF_INT128__)
|
||||
|
||||
inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
|
||||
{
|
||||
__uint128_t r = static_cast<__uint128_t>( x ) * y;
|
||||
return static_cast<std::uint64_t>( r ) ^ static_cast<std::uint64_t>( r >> 64 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
|
||||
{
|
||||
std::uint64_t x1 = static_cast<std::uint32_t>( x );
|
||||
std::uint64_t x2 = x >> 32;
|
||||
|
||||
std::uint64_t y1 = static_cast<std::uint32_t>( y );
|
||||
std::uint64_t y2 = y >> 32;
|
||||
|
||||
std::uint64_t r3 = x2 * y2;
|
||||
|
||||
std::uint64_t r2a = x1 * y2;
|
||||
|
||||
r3 += r2a >> 32;
|
||||
|
||||
std::uint64_t r2b = x2 * y1;
|
||||
|
||||
r3 += r2b >> 32;
|
||||
|
||||
std::uint64_t r1 = x1 * y1;
|
||||
|
||||
std::uint64_t r2 = (r1 >> 32) + static_cast<std::uint32_t>( r2a ) + static_cast<std::uint32_t>( r2b );
|
||||
|
||||
r1 = (r2 << 32) + static_cast<std::uint32_t>( r1 );
|
||||
r3 += r2 >> 32;
|
||||
|
||||
return r1 ^ r3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace hash_detail
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_DETAIL_MULX_HPP
|
576
boost/container_hash/hash.hpp
Normal file
576
boost/container_hash/hash.hpp
Normal file
@ -0,0 +1,576 @@
|
||||
// Copyright 2005-2014 Daniel James.
|
||||
// Copyright 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Based on Peter Dimov's proposal
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
|
||||
// issue 6.18.
|
||||
|
||||
#ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
#define BOOST_FUNCTIONAL_HASH_HASH_HPP
|
||||
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/container_hash/is_range.hpp>
|
||||
#include <boost/container_hash/is_contiguous_range.hpp>
|
||||
#include <boost/container_hash/is_unordered_range.hpp>
|
||||
#include <boost/container_hash/is_described_class.hpp>
|
||||
#include <boost/container_hash/detail/hash_integral.hpp>
|
||||
#include <boost/container_hash/detail/hash_tuple_like.hpp>
|
||||
#include <boost/container_hash/detail/hash_mix.hpp>
|
||||
#include <boost/container_hash/detail/hash_range.hpp>
|
||||
#include <boost/describe/bases.hpp>
|
||||
#include <boost/describe/members.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX14)
|
||||
# include <boost/mp11/algorithm.hpp>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <complex>
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
#include <cstring>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
#include <typeindex>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
#include <system_error>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL)
|
||||
#include <optional>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_VARIANT)
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||
# include <string_view>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
//
|
||||
// boost::hash_value
|
||||
//
|
||||
|
||||
// integral types
|
||||
// in detail/hash_integral.hpp
|
||||
|
||||
// enumeration types
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_enum<T>::value, std::size_t>::type
|
||||
hash_value( T v )
|
||||
{
|
||||
// This should in principle return the equivalent of
|
||||
//
|
||||
// boost::hash_value( to_underlying(v) );
|
||||
//
|
||||
// However, the C++03 implementation of underlying_type,
|
||||
//
|
||||
// conditional<is_signed<T>, make_signed<T>, make_unsigned<T>>::type::type
|
||||
//
|
||||
// generates a legitimate -Wconversion warning in is_signed,
|
||||
// because -1 is not a valid enum value when all the enumerators
|
||||
// are nonnegative.
|
||||
//
|
||||
// So the legacy implementation will have to do for now.
|
||||
|
||||
return static_cast<std::size_t>( v );
|
||||
}
|
||||
|
||||
// floating point types
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
template<class T,
|
||||
std::size_t Bits = sizeof(T) * CHAR_BIT,
|
||||
int Digits = std::numeric_limits<T>::digits>
|
||||
struct hash_float_impl;
|
||||
|
||||
// float
|
||||
template<class T, int Digits> struct hash_float_impl<T, 32, Digits>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::uint32_t w;
|
||||
std::memcpy( &w, &v, sizeof( v ) );
|
||||
|
||||
return w;
|
||||
}
|
||||
};
|
||||
|
||||
// double
|
||||
template<class T, int Digits> struct hash_float_impl<T, 64, Digits>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::uint64_t w;
|
||||
std::memcpy( &w, &v, sizeof( v ) );
|
||||
|
||||
return hash_value( w );
|
||||
}
|
||||
};
|
||||
|
||||
// 80 bit long double in 12 bytes
|
||||
template<class T> struct hash_float_impl<T, 96, 64>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::uint64_t w[ 2 ] = {};
|
||||
std::memcpy( &w, &v, 80 / CHAR_BIT );
|
||||
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed = hash_value( w[0] ) + hash_detail::hash_mix( seed );
|
||||
seed = hash_value( w[1] ) + hash_detail::hash_mix( seed );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
// 80 bit long double in 16 bytes
|
||||
template<class T> struct hash_float_impl<T, 128, 64>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::uint64_t w[ 2 ] = {};
|
||||
std::memcpy( &w, &v, 80 / CHAR_BIT );
|
||||
|
||||
std::size_t seed = 0;
|
||||
|
||||
seed = hash_value( w[0] ) + hash_detail::hash_mix( seed );
|
||||
seed = hash_value( w[1] ) + hash_detail::hash_mix( seed );
|
||||
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
// 128 bit long double
|
||||
template<class T, int Digits> struct hash_float_impl<T, 128, Digits>
|
||||
{
|
||||
static std::size_t fn( T v )
|
||||
{
|
||||
std::uint64_t w[ 2 ];
|
||||
std::memcpy( &w, &v, sizeof( v ) );
|
||||
|
||||
std::size_t seed = 0;
|
||||
|
||||
#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
seed = hash_value( w[1] ) + hash_detail::hash_mix( seed );
|
||||
seed = hash_value( w[0] ) + hash_detail::hash_mix( seed );
|
||||
|
||||
#else
|
||||
|
||||
seed = hash_value( w[0] ) + hash_detail::hash_mix( seed );
|
||||
seed = hash_value( w[1] ) + hash_detail::hash_mix( seed );
|
||||
|
||||
#endif
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, std::size_t>::type
|
||||
hash_value( T v )
|
||||
{
|
||||
return boost::hash_detail::hash_float_impl<T>::fn( v + 0 );
|
||||
}
|
||||
|
||||
// pointer types
|
||||
|
||||
// `x + (x >> 3)` adjustment by Alberto Barbati and Dave Harris.
|
||||
template <class T> std::size_t hash_value( T* const& v )
|
||||
{
|
||||
std::uintptr_t x = reinterpret_cast<std::uintptr_t>( v );
|
||||
return boost::hash_value( x + (x >> 3) );
|
||||
}
|
||||
|
||||
// array types
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline std::size_t hash_value( T const (&x)[ N ] )
|
||||
{
|
||||
return boost::hash_range( x, x + N );
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
inline std::size_t hash_value( T (&x)[ N ] )
|
||||
{
|
||||
return boost::hash_range( x, x + N );
|
||||
}
|
||||
|
||||
// complex
|
||||
|
||||
template <class T>
|
||||
std::size_t hash_value( std::complex<T> const& v )
|
||||
{
|
||||
std::size_t re = boost::hash<T>()( v.real() );
|
||||
std::size_t im = boost::hash<T>()( v.imag() );
|
||||
|
||||
return re + hash_detail::hash_mix( im );
|
||||
}
|
||||
|
||||
// pair
|
||||
|
||||
template <class A, class B>
|
||||
std::size_t hash_value( std::pair<A, B> const& v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
boost::hash_combine( seed, v.first );
|
||||
boost::hash_combine( seed, v.second );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
// ranges (list, set, deque...)
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<container_hash::is_range<T>::value && !container_hash::is_contiguous_range<T>::value && !container_hash::is_unordered_range<T>::value, std::size_t>::type
|
||||
hash_value( T const& v )
|
||||
{
|
||||
return boost::hash_range( v.begin(), v.end() );
|
||||
}
|
||||
|
||||
// contiguous ranges (string, vector, array)
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<container_hash::is_contiguous_range<T>::value, std::size_t>::type
|
||||
hash_value( T const& v )
|
||||
{
|
||||
return boost::hash_range( v.data(), v.data() + v.size() );
|
||||
}
|
||||
|
||||
// unordered ranges (unordered_set, unordered_map)
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<container_hash::is_unordered_range<T>::value, std::size_t>::type
|
||||
hash_value( T const& v )
|
||||
{
|
||||
return boost::hash_unordered_range( v.begin(), v.end() );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \
|
||||
( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \
|
||||
( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) )
|
||||
|
||||
// resolve ambiguity with unconstrained stdext::hash_value in <xhash> :-/
|
||||
|
||||
template<template<class...> class L, class... T>
|
||||
typename std::enable_if<container_hash::is_range<L<T...>>::value && !container_hash::is_contiguous_range<L<T...>>::value && !container_hash::is_unordered_range<L<T...>>::value, std::size_t>::type
|
||||
hash_value( L<T...> const& v )
|
||||
{
|
||||
return boost::hash_range( v.begin(), v.end() );
|
||||
}
|
||||
|
||||
// contiguous ranges (string, vector, array)
|
||||
|
||||
template<template<class...> class L, class... T>
|
||||
typename std::enable_if<container_hash::is_contiguous_range<L<T...>>::value, std::size_t>::type
|
||||
hash_value( L<T...> const& v )
|
||||
{
|
||||
return boost::hash_range( v.data(), v.data() + v.size() );
|
||||
}
|
||||
|
||||
template<template<class, std::size_t> class L, class T, std::size_t N>
|
||||
typename std::enable_if<container_hash::is_contiguous_range<L<T, N>>::value, std::size_t>::type
|
||||
hash_value( L<T, N> const& v )
|
||||
{
|
||||
return boost::hash_range( v.data(), v.data() + v.size() );
|
||||
}
|
||||
|
||||
// unordered ranges (unordered_set, unordered_map)
|
||||
|
||||
template<template<class...> class L, class... T>
|
||||
typename std::enable_if<container_hash::is_unordered_range<L<T...>>::value, std::size_t>::type
|
||||
hash_value( L<T...> const& v )
|
||||
{
|
||||
return boost::hash_unordered_range( v.begin(), v.end() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// described classes
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX14)
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1900
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4100) // unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<container_hash::is_described_class<T>::value, std::size_t>::type
|
||||
hash_value( T const& v )
|
||||
{
|
||||
static_assert( !std::is_union<T>::value, "described unions are not supported" );
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
using Bd = describe::describe_bases<T, describe::mod_any_access>;
|
||||
|
||||
mp11::mp_for_each<Bd>([&](auto D){
|
||||
|
||||
using B = typename decltype(D)::type;
|
||||
boost::hash_combine( r, (B const&)v );
|
||||
|
||||
});
|
||||
|
||||
using Md = describe::describe_members<T, describe::mod_any_access>;
|
||||
|
||||
mp11::mp_for_each<Md>([&](auto D){
|
||||
|
||||
boost::hash_combine( r, v.*D.pointer );
|
||||
|
||||
});
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1900
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// std::unique_ptr, std::shared_ptr
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
|
||||
template <typename T>
|
||||
std::size_t hash_value( std::shared_ptr<T> const& x )
|
||||
{
|
||||
return boost::hash_value( x.get() );
|
||||
}
|
||||
|
||||
template <typename T, typename Deleter>
|
||||
std::size_t hash_value( std::unique_ptr<T, Deleter> const& x )
|
||||
{
|
||||
return boost::hash_value( x.get() );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// std::type_index
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPEINDEX)
|
||||
|
||||
inline std::size_t hash_value( std::type_index const& v )
|
||||
{
|
||||
return v.hash_code();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// std::error_code, std::error_condition
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
|
||||
inline std::size_t hash_value( std::error_code const& v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
boost::hash_combine( seed, v.value() );
|
||||
boost::hash_combine( seed, &v.category() );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
inline std::size_t hash_value( std::error_condition const& v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
boost::hash_combine( seed, v.value() );
|
||||
boost::hash_combine( seed, &v.category() );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// std::nullptr_t
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_same<T, std::nullptr_t>::value, std::size_t>::type
|
||||
hash_value( T const& /*v*/ )
|
||||
{
|
||||
return boost::hash_value( static_cast<void*>( nullptr ) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// std::optional
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_OPTIONAL)
|
||||
|
||||
template <typename T>
|
||||
std::size_t hash_value( std::optional<T> const& v )
|
||||
{
|
||||
if( !v )
|
||||
{
|
||||
// Arbitrary value for empty optional.
|
||||
return 0x12345678;
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::hash<T>()(*v);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// std::variant
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_VARIANT)
|
||||
|
||||
inline std::size_t hash_value( std::monostate )
|
||||
{
|
||||
return 0x87654321;
|
||||
}
|
||||
|
||||
template <typename... Types>
|
||||
std::size_t hash_value( std::variant<Types...> const& v )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
hash_combine( seed, v.index() );
|
||||
std::visit( [&seed](auto&& x) { hash_combine(seed, x); }, v );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost::hash_combine
|
||||
//
|
||||
|
||||
template <class T>
|
||||
inline void hash_combine( std::size_t& seed, T const& v )
|
||||
{
|
||||
seed = boost::hash_detail::hash_mix( seed + 0x9e3779b9 + boost::hash<T>()( v ) );
|
||||
}
|
||||
|
||||
//
|
||||
// boost::hash_range
|
||||
//
|
||||
|
||||
template <class It>
|
||||
inline void hash_range( std::size_t& seed, It first, It last )
|
||||
{
|
||||
seed = hash_detail::hash_range( seed, first, last );
|
||||
}
|
||||
|
||||
template <class It>
|
||||
inline std::size_t hash_range( It first, It last )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
hash_range( seed, first, last );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
//
|
||||
// boost::hash_unordered_range
|
||||
//
|
||||
|
||||
template <class It>
|
||||
inline void hash_unordered_range( std::size_t& seed, It first, It last )
|
||||
{
|
||||
std::size_t r = 0;
|
||||
std::size_t const s2( seed );
|
||||
|
||||
for( ; first != last; ++first )
|
||||
{
|
||||
std::size_t s3( s2 );
|
||||
|
||||
hash_combine<typename std::iterator_traits<It>::value_type>( s3, *first );
|
||||
|
||||
r += s3;
|
||||
}
|
||||
|
||||
seed += r;
|
||||
}
|
||||
|
||||
template <class It>
|
||||
inline std::size_t hash_unordered_range( It first, It last )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
|
||||
hash_unordered_range( seed, first, last );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
//
|
||||
// boost::hash
|
||||
//
|
||||
|
||||
template <class T> struct hash
|
||||
{
|
||||
typedef T argument_type;
|
||||
typedef std::size_t result_type;
|
||||
|
||||
std::size_t operator()( T const& val ) const
|
||||
{
|
||||
return hash_value( val );
|
||||
}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && ( \
|
||||
( defined(_MSVC_STL_VERSION) && _MSVC_STL_VERSION < 142 ) || \
|
||||
( !defined(_MSVC_STL_VERSION) && defined(_CPPLIB_VER) && _CPPLIB_VER >= 520 ) )
|
||||
|
||||
// Dinkumware has stdext::hash_value for basic_string in <xhash> :-/
|
||||
|
||||
template<class E, class T, class A> struct hash< std::basic_string<E, T, A> >
|
||||
{
|
||||
typedef std::basic_string<E, T, A> argument_type;
|
||||
typedef std::size_t result_type;
|
||||
|
||||
std::size_t operator()( std::basic_string<E, T, A> const& val ) const
|
||||
{
|
||||
return boost::hash_value( val );
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// boost::unordered::hash_is_avalanching
|
||||
|
||||
namespace unordered
|
||||
{
|
||||
template<class T> struct hash_is_avalanching;
|
||||
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string<Ch> > >: std::is_integral<Ch> {};
|
||||
|
||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||
|
||||
template<class Ch> struct hash_is_avalanching< boost::hash< std::basic_string_view<Ch> > >: std::is_integral<Ch> {};
|
||||
|
||||
#endif
|
||||
} // namespace unordered
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_HPP
|
37
boost/container_hash/hash_fwd.hpp
Normal file
37
boost/container_hash/hash_fwd.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2005-2009 Daniel James.
|
||||
// Copyright 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||
#define BOOST_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_range;
|
||||
template<class T> struct is_contiguous_range;
|
||||
template<class T> struct is_unordered_range;
|
||||
template<class T> struct is_described_class;
|
||||
template<class T> struct is_tuple_like;
|
||||
|
||||
} // namespace container_hash
|
||||
|
||||
template<class T> struct hash;
|
||||
|
||||
template<class T> void hash_combine( std::size_t& seed, T const& v );
|
||||
|
||||
template<class It> void hash_range( std::size_t&, It, It );
|
||||
template<class It> std::size_t hash_range( It, It );
|
||||
|
||||
template<class It> void hash_unordered_range( std::size_t&, It, It );
|
||||
template<class It> std::size_t hash_unordered_range( It, It );
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_FUNCTIONAL_HASH_FWD_HPP
|
98
boost/container_hash/is_contiguous_range.hpp
Normal file
98
boost/container_hash/is_contiguous_range.hpp
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright 2017, 2018 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
|
||||
#define BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
|
||||
|
||||
#include <boost/container_hash/is_range.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<class It, class T, class S>
|
||||
std::integral_constant< bool, std::is_same<typename std::iterator_traits<It>::value_type, T>::value && std::is_integral<S>::value >
|
||||
is_contiguous_range_check( It first, It last, T const*, T const*, S );
|
||||
|
||||
template<class T> decltype( is_contiguous_range_check( std::declval<T const&>().begin(), std::declval<T const&>().end(), std::declval<T const&>().data(), std::declval<T const&>().data() + std::declval<T const&>().size(), std::declval<T const&>().size() ) ) is_contiguous_range_( int );
|
||||
template<class T> std::false_type is_contiguous_range_( ... );
|
||||
|
||||
template<class T> struct is_contiguous_range: decltype( hash_detail::is_contiguous_range_<T>( 0 ) )
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_contiguous_range: std::integral_constant< bool, is_range<T>::value && hash_detail::is_contiguous_range<T>::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace container_hash
|
||||
} // namespace boost
|
||||
|
||||
#else // !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_contiguous_range: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class E, class T, class A> struct is_contiguous_range< std::basic_string<E, T, A> >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class E, class T, class A> struct is_contiguous_range< std::basic_string<E, T, A> const >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class A> struct is_contiguous_range< std::vector<T, A> >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class A> struct is_contiguous_range< std::vector<T, A> const >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class A> struct is_contiguous_range< std::vector<bool, A> >: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class A> struct is_contiguous_range< std::vector<bool, A> const >: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, std::size_t N> struct is_contiguous_range< std::array<T, N> >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, std::size_t N> struct is_contiguous_range< std::array<T, N> const >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace container_hash
|
||||
} // namespace boost
|
||||
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
|
||||
#endif // #ifndef BOOST_HASH_IS_CONTIGUOUS_RANGE_HPP_INCLUDED
|
37
boost/container_hash/is_described_class.hpp
Normal file
37
boost/container_hash/is_described_class.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED
|
||||
#define BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED
|
||||
|
||||
#include <boost/describe/bases.hpp>
|
||||
#include <boost/describe/members.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
template<class T> struct is_described_class: std::integral_constant<bool,
|
||||
describe::has_describe_bases<T>::value &&
|
||||
describe::has_describe_members<T>::value &&
|
||||
!std::is_union<T>::value>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T> struct is_described_class: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace container_hash
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_IS_DESCRIBED_CLASS_HPP_INCLUDED
|
37
boost/container_hash/is_range.hpp
Normal file
37
boost/container_hash/is_range.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright 2017 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED
|
||||
#define BOOST_HASH_IS_RANGE_HPP_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<class T, class It>
|
||||
std::integral_constant< bool, !std::is_same<typename std::remove_cv<T>::type, typename std::iterator_traits<It>::value_type>::value >
|
||||
is_range_check( It first, It last );
|
||||
|
||||
template<class T> decltype( is_range_check<T>( std::declval<T const&>().begin(), std::declval<T const&>().end() ) ) is_range_( int );
|
||||
template<class T> std::false_type is_range_( ... );
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_range: decltype( hash_detail::is_range_<T>( 0 ) )
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace container_hash
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_IS_RANGE_HPP_INCLUDED
|
36
boost/container_hash/is_tuple_like.hpp
Normal file
36
boost/container_hash/is_tuple_like.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED
|
||||
#define BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<class T, class E = std::true_type> struct is_tuple_like_: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct is_tuple_like_<T, std::integral_constant<bool, std::tuple_size<T>::value == std::tuple_size<T>::value> >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_tuple_like: hash_detail::is_tuple_like_<T>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace container_hash
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_IS_TUPLE_LIKE_HPP_INCLUDED
|
38
boost/container_hash/is_unordered_range.hpp
Normal file
38
boost/container_hash/is_unordered_range.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2017 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED
|
||||
#define BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED
|
||||
|
||||
#include <boost/container_hash/is_range.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace hash_detail
|
||||
{
|
||||
|
||||
template<class T, class E = std::true_type> struct has_hasher_: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct has_hasher_< T, std::integral_constant< bool,
|
||||
std::is_same<typename T::hasher, typename T::hasher>::value
|
||||
> >: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace hash_detail
|
||||
|
||||
namespace container_hash
|
||||
{
|
||||
|
||||
template<class T> struct is_unordered_range: std::integral_constant< bool, is_range<T>::value && hash_detail::has_hasher_<T>::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace container_hash
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_HASH_IS_UNORDERED_RANGE_HPP_INCLUDED
|
39
boost/core/detail/is_same.hpp
Normal file
39
boost/core/detail/is_same.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
||||
#define BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
||||
|
||||
// is_same<T1,T2>::value is true when T1 == T2
|
||||
//
|
||||
// Copyright 2014 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace core
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class T1, class T2 > struct is_same
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = false );
|
||||
};
|
||||
|
||||
template< class T > struct is_same< T, T >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_DETAIL_IS_SAME_HPP_INCLUDED
|
163
boost/core/explicit_operator_bool.hpp
Normal file
163
boost/core/explicit_operator_bool.hpp
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2007 - 2013.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file explicit_operator_bool.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 08.03.2009
|
||||
*
|
||||
* This header defines a compatibility macro that implements an unspecified
|
||||
* \c bool operator idiom, which is superseded with explicit conversion operators in
|
||||
* C++11.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
|
||||
#define BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
/*!
|
||||
* \brief The macro defines an explicit operator of conversion to \c bool
|
||||
*
|
||||
* The macro should be used inside the definition of a class that has to
|
||||
* support the conversion. The class should also implement <tt>operator!</tt>,
|
||||
* in terms of which the conversion operator will be implemented.
|
||||
*/
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE explicit operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief The macro defines a noexcept explicit operator of conversion to \c bool
|
||||
*
|
||||
* The macro should be used inside the definition of a class that has to
|
||||
* support the conversion. The class should also implement <tt>operator!</tt>,
|
||||
* in terms of which the conversion operator will be implemented.
|
||||
*/
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
|
||||
BOOST_FORCEINLINE explicit operator bool () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_GCC, < 40700)
|
||||
|
||||
/*!
|
||||
* \brief The macro defines a constexpr explicit operator of conversion to \c bool
|
||||
*
|
||||
* The macro should be used inside the definition of a class that has to
|
||||
* support the conversion. The class should also implement <tt>operator!</tt>,
|
||||
* in terms of which the conversion operator will be implemented.
|
||||
*/
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
|
||||
|
||||
#endif
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
|
||||
// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
|
||||
#define BOOST_NO_UNSPECIFIED_BOOL
|
||||
#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
|
||||
|
||||
#if !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
#if !defined(_MSC_VER) && !defined(__IBMCPP__)
|
||||
|
||||
struct unspecified_bool
|
||||
{
|
||||
// NOTE TO THE USER: If you see this in error messages then you tried
|
||||
// to apply an unsupported operator on the object that supports
|
||||
// explicit conversion to bool.
|
||||
struct OPERATORS_NOT_ALLOWED;
|
||||
static void true_value(OPERATORS_NOT_ALLOWED*) {}
|
||||
};
|
||||
typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
|
||||
|
||||
#else
|
||||
|
||||
// MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't
|
||||
struct unspecified_bool
|
||||
{
|
||||
// NOTE TO THE USER: If you see this in error messages then you tried
|
||||
// to apply an unsupported operator on the object that supports
|
||||
// explicit conversion to bool.
|
||||
struct OPERATORS_NOT_ALLOWED;
|
||||
void true_value(OPERATORS_NOT_ALLOWED*) {}
|
||||
};
|
||||
typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\
|
||||
{\
|
||||
return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
|
||||
}
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
|
||||
BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
|
||||
}
|
||||
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE operator bool () const\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
|
||||
BOOST_FORCEINLINE operator bool () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
|
||||
BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const BOOST_NOEXCEPT\
|
||||
{\
|
||||
return !this->operator! ();\
|
||||
}
|
||||
|
||||
#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL)
|
||||
|
||||
#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
|
||||
|
||||
#endif // BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
|
93
boost/core/invoke_swap.hpp
Normal file
93
boost/core/invoke_swap.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
|
||||
// Copyright (C) 2023 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
// For more information, see http://www.boost.org
|
||||
|
||||
#ifndef BOOST_CORE_INVOKE_SWAP_HPP
|
||||
#define BOOST_CORE_INVOKE_SWAP_HPP
|
||||
|
||||
// Note: the implementation of this utility contains various workarounds:
|
||||
// - invoke_swap_impl is put outside the boost namespace, to avoid infinite
|
||||
// recursion (causing stack overflow) when swapping objects of a primitive
|
||||
// type.
|
||||
// - std::swap is imported with a using-directive, rather than
|
||||
// a using-declaration, because some compilers (including MSVC 7.1,
|
||||
// Borland 5.9.3, and Intel 8.1) don't do argument-dependent lookup
|
||||
// when it has a using-declaration instead.
|
||||
// - The main entry function is called invoke_swap rather than swap
|
||||
// to avoid forming an infinite recursion when the arguments are not
|
||||
// swappable.
|
||||
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB)
|
||||
#include <utility> // for std::swap (C++11)
|
||||
#else
|
||||
#include <algorithm> // for std::swap (C++98)
|
||||
#endif
|
||||
#include <cstddef> // for std::size_t
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC < 40700)
|
||||
// gcc 4.6 ICEs on noexcept specifications below
|
||||
#define BOOST_CORE_SWAP_NOEXCEPT_IF(x)
|
||||
#else
|
||||
#define BOOST_CORE_SWAP_NOEXCEPT_IF(x) BOOST_NOEXCEPT_IF(x)
|
||||
#endif
|
||||
|
||||
namespace boost_swap_impl {
|
||||
|
||||
// we can't use type_traits here
|
||||
|
||||
template<class T> struct is_const { enum _vt { value = 0 }; };
|
||||
template<class T> struct is_const<T const> { enum _vt { value = 1 }; };
|
||||
|
||||
// Use std::swap if argument dependent lookup fails.
|
||||
// We need to have this at namespace scope to be able to use unqualified swap() call
|
||||
// in noexcept specification.
|
||||
using namespace std;
|
||||
|
||||
template<class T>
|
||||
BOOST_GPU_ENABLED
|
||||
inline void invoke_swap_impl(T& left, T& right) BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(swap(left, right)))
|
||||
{
|
||||
swap(left, right);
|
||||
}
|
||||
|
||||
template<class T, std::size_t N>
|
||||
BOOST_GPU_ENABLED
|
||||
inline void invoke_swap_impl(T (& left)[N], T (& right)[N])
|
||||
BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left[0], right[0])))
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
::boost_swap_impl::invoke_swap_impl(left[i], right[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost_swap_impl
|
||||
|
||||
namespace boost {
|
||||
namespace core {
|
||||
|
||||
template<class T>
|
||||
BOOST_GPU_ENABLED
|
||||
inline typename enable_if_c< !::boost_swap_impl::is_const<T>::value >::type
|
||||
invoke_swap(T& left, T& right)
|
||||
BOOST_CORE_SWAP_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(::boost_swap_impl::invoke_swap_impl(left, right)))
|
||||
{
|
||||
::boost_swap_impl::invoke_swap_impl(left, right);
|
||||
}
|
||||
|
||||
} // namespace core
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_CORE_SWAP_NOEXCEPT_IF
|
||||
|
||||
#endif // BOOST_CORE_INVOKE_SWAP_HPP
|
91
boost/core/lightweight_test_trait.hpp
Normal file
91
boost/core/lightweight_test_trait.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef BOOST_CORE_LIGHTWEIGHT_TEST_TRAIT_HPP
|
||||
#define BOOST_CORE_LIGHTWEIGHT_TEST_TRAIT_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
// boost/core/lightweight_test_trait.hpp
|
||||
//
|
||||
// BOOST_TEST_TRAIT_TRUE, BOOST_TEST_TRAIT_FALSE, BOOST_TEST_TRAIT_SAME
|
||||
//
|
||||
// Copyright 2014, 2021 Peter Dimov
|
||||
//
|
||||
// Copyright 2019 Glen Joseph Fernandes
|
||||
// (glenjofe@gmail.com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include <boost/core/type_name.hpp>
|
||||
#include <boost/core/detail/is_same.hpp>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class T > inline void test_trait_impl( char const * trait, void (*)( T ),
|
||||
bool expected, char const * file, int line, char const * function )
|
||||
{
|
||||
if( T::value == expected )
|
||||
{
|
||||
test_results();
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): predicate '" << trait << "' ["
|
||||
<< boost::core::type_name<T>() << "]"
|
||||
<< " test failed in function '" << function
|
||||
<< "' (should have been " << ( expected? "true": "false" ) << ")"
|
||||
<< std::endl;
|
||||
|
||||
++test_results().errors();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T> inline bool test_trait_same_impl_( T )
|
||||
{
|
||||
return T::value;
|
||||
}
|
||||
|
||||
template<class T1, class T2> inline void test_trait_same_impl( char const * types,
|
||||
boost::core::detail::is_same<T1, T2> same, char const * file, int line, char const * function )
|
||||
{
|
||||
if( test_trait_same_impl_( same ) )
|
||||
{
|
||||
test_results();
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< file << "(" << line << "): test 'is_same<" << types << ">'"
|
||||
<< " failed in function '" << function
|
||||
<< "' ('" << boost::core::type_name<T1>()
|
||||
<< "' != '" << boost::core::type_name<T2>() << "')"
|
||||
<< std::endl;
|
||||
|
||||
++test_results().errors();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
#define BOOST_TEST_TRAIT_FALSE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, false, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
|
||||
#if defined(__GNUC__)
|
||||
// ignoring -Wvariadic-macros with #pragma doesn't work under GCC
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#define BOOST_TEST_TRAIT_SAME(...) ( ::boost::detail::test_trait_same_impl(#__VA_ARGS__, ::boost::core::detail::is_same< __VA_ARGS__ >(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||
|
||||
#endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_TRAIT_HPP
|
345
boost/core/ref.hpp
Normal file
345
boost/core/ref.hpp
Normal file
@ -0,0 +1,345 @@
|
||||
#ifndef BOOST_CORE_REF_HPP
|
||||
#define BOOST_CORE_REF_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// ref.hpp - ref/cref, useful helper functions
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2001, 2002 Peter Dimov
|
||||
// Copyright (C) 2002 David Abrahams
|
||||
//
|
||||
// Copyright (C) 2014 Glen Joseph Fernandes
|
||||
// (glenjofe@gmail.com)
|
||||
//
|
||||
// Copyright (C) 2014 Agustin Berge
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation.
|
||||
//
|
||||
|
||||
/**
|
||||
@file
|
||||
*/
|
||||
|
||||
/**
|
||||
Boost namespace.
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
|
||||
|
||||
struct ref_workaround_tag {};
|
||||
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template< class Y, class T > struct ref_convertible
|
||||
{
|
||||
typedef char (&yes) [1];
|
||||
typedef char (&no) [2];
|
||||
|
||||
static yes f( T* );
|
||||
static no f( ... );
|
||||
|
||||
enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
struct ref_empty
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// reference_wrapper
|
||||
|
||||
/**
|
||||
@brief Contains a reference to an object of type `T`.
|
||||
|
||||
`reference_wrapper` is primarily used to "feed" references to
|
||||
function templates (algorithms) that take their parameter by
|
||||
value. It provides an implicit conversion to `T&`, which
|
||||
usually allows the function templates to work on references
|
||||
unmodified.
|
||||
*/
|
||||
template<class T> class reference_wrapper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Type `T`.
|
||||
*/
|
||||
typedef T type;
|
||||
|
||||
/**
|
||||
Constructs a `reference_wrapper` object that stores a
|
||||
reference to `t`.
|
||||
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE explicit reference_wrapper(T& t) BOOST_NOEXCEPT : t_(boost::addressof(t)) {}
|
||||
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
|
||||
|
||||
BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ) BOOST_NOEXCEPT : t_( boost::addressof( t ) ) {}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
/**
|
||||
@remark Construction from a temporary object is disabled.
|
||||
*/
|
||||
BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
|
||||
public:
|
||||
#endif
|
||||
|
||||
template<class Y> friend class reference_wrapper;
|
||||
|
||||
/**
|
||||
Constructs a `reference_wrapper` object that stores the
|
||||
reference stored in the compatible `reference_wrapper` `r`.
|
||||
|
||||
@remark Only enabled when `Y*` is convertible to `T*`.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
#if !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS)
|
||||
template<class Y, class = typename enable_if_c<boost::detail::ref_convertible<Y, T>::value>::type>
|
||||
reference_wrapper( reference_wrapper<Y> r ) BOOST_NOEXCEPT : t_( r.t_ )
|
||||
{
|
||||
}
|
||||
#else
|
||||
template<class Y> reference_wrapper( reference_wrapper<Y> r,
|
||||
typename enable_if_c<boost::detail::ref_convertible<Y, T>::value,
|
||||
boost::detail::ref_empty>::type = boost::detail::ref_empty() ) BOOST_NOEXCEPT : t_( r.t_ )
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
@return The stored reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE operator T& () const BOOST_NOEXCEPT { return *t_; }
|
||||
|
||||
/**
|
||||
@return The stored reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE T& get() const BOOST_NOEXCEPT { return *t_; }
|
||||
|
||||
/**
|
||||
@return A pointer to the object referenced by the stored
|
||||
reference.
|
||||
@remark Does not throw.
|
||||
*/
|
||||
BOOST_FORCEINLINE T* get_pointer() const BOOST_NOEXCEPT { return t_; }
|
||||
|
||||
private:
|
||||
|
||||
T* t_;
|
||||
};
|
||||
|
||||
// ref
|
||||
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
#if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) )
|
||||
# define BOOST_REF_CONST
|
||||
#else
|
||||
# define BOOST_REF_CONST const
|
||||
#endif
|
||||
/**
|
||||
@endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
@return `reference_wrapper<T>(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
|
||||
|
||||
return reference_wrapper<T>( t, ref_workaround_tag() );
|
||||
|
||||
#else
|
||||
|
||||
return reference_wrapper<T>( t );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// cref
|
||||
|
||||
/**
|
||||
@return `reference_wrapper<T const>(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return reference_wrapper<T const>(t);
|
||||
}
|
||||
|
||||
#undef BOOST_REF_CONST
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
# define BOOST_REF_DELETE
|
||||
#else
|
||||
# define BOOST_REF_DELETE = delete
|
||||
#endif
|
||||
/**
|
||||
@endcond
|
||||
*/
|
||||
|
||||
/**
|
||||
@remark Construction from a temporary object is disabled.
|
||||
*/
|
||||
template<class T> void ref(T const&&) BOOST_REF_DELETE;
|
||||
|
||||
/**
|
||||
@remark Construction from a temporary object is disabled.
|
||||
*/
|
||||
template<class T> void cref(T const&&) BOOST_REF_DELETE;
|
||||
|
||||
#undef BOOST_REF_DELETE
|
||||
|
||||
#endif
|
||||
|
||||
// is_reference_wrapper
|
||||
|
||||
/**
|
||||
@brief Determine if a type `T` is an instantiation of
|
||||
`reference_wrapper`.
|
||||
|
||||
The value static constant will be true if the type `T` is a
|
||||
specialization of `reference_wrapper`.
|
||||
*/
|
||||
template<typename T> struct is_reference_wrapper
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = false );
|
||||
};
|
||||
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
|
||||
|
||||
template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
|
||||
{
|
||||
BOOST_STATIC_CONSTANT( bool, value = true );
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
|
||||
|
||||
/**
|
||||
@endcond
|
||||
*/
|
||||
|
||||
|
||||
// unwrap_reference
|
||||
|
||||
/**
|
||||
@brief Find the type in a `reference_wrapper`.
|
||||
|
||||
The `typedef` type is `T::type` if `T` is a
|
||||
`reference_wrapper`, `T` otherwise.
|
||||
*/
|
||||
template<typename T> struct unwrap_reference
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
template<typename T> struct unwrap_reference< reference_wrapper<T> >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
|
||||
|
||||
template<typename T> struct unwrap_reference< reference_wrapper<T> const >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
|
||||
|
||||
/**
|
||||
@endcond
|
||||
*/
|
||||
|
||||
// unwrap_ref
|
||||
|
||||
/**
|
||||
@return `unwrap_reference<T>::type&(t)`
|
||||
@remark Does not throw.
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t ) BOOST_NOEXCEPT
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
// get_pointer
|
||||
|
||||
/**
|
||||
@cond
|
||||
*/
|
||||
template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r ) BOOST_NOEXCEPT
|
||||
{
|
||||
return r.get_pointer();
|
||||
}
|
||||
/**
|
||||
@endcond
|
||||
*/
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_CORE_REF_HPP
|
173
boost/core/snprintf.hpp
Normal file
173
boost/core/snprintf.hpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright Andrey Semashev 2022.
|
||||
* Distributed under the Boost Software License, Version 1.0.
|
||||
* (See accompanying file LICENSE_1_0.txt or copy at
|
||||
* http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
/*!
|
||||
* \file snprintf.hpp
|
||||
* \author Andrey Semashev
|
||||
* \date 06.12.2022
|
||||
*
|
||||
* \brief The header provides more portable definition of snprintf and vsnprintf,
|
||||
* as well as \c wchar_t counterparts.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
||||
#define BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
#if !defined(__MINGW64_VERSION_MAJOR)
|
||||
#include <climits>
|
||||
#endif
|
||||
|
||||
// MinGW32 and MinGW-w64 provide their own snprintf implementations that are compliant with the C standard.
|
||||
#define BOOST_CORE_DETAIL_MINGW_SNPRINTF
|
||||
|
||||
#elif (defined(BOOST_MSSTL_VERSION) && BOOST_MSSTL_VERSION < 140)
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdarg>
|
||||
#include <climits>
|
||||
|
||||
// MSVC snprintfs are not conforming but they are good enough for typical use cases.
|
||||
#define BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace core {
|
||||
|
||||
#if defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
#if defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF)
|
||||
|
||||
inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
|
||||
{
|
||||
return __mingw_vsnprintf(buf, size, format, args);
|
||||
}
|
||||
|
||||
inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
|
||||
{
|
||||
#if defined(__MINGW64_VERSION_MAJOR)
|
||||
int res = __mingw_vsnwprintf(buf, size, format, args);
|
||||
// __mingw_vsnwprintf returns the number of characters to be printed, but (v)swprintf is expected to return -1 on truncation
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
res = -1;
|
||||
return res;
|
||||
#else
|
||||
// Legacy MinGW32 does not provide __mingw_vsnwprintf, so use _vsnwprintf from MSVC CRT
|
||||
if (BOOST_UNLIKELY(size == 0u || size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
int res = _vsnwprintf(buf, size, format, args);
|
||||
// (v)swprintf is expected to return -1 on truncation, so we only need to ensure the output is null-terminated
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
buf[size - 1u] = L'\0';
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
// '_vsnprintf': This function or variable may be unsafe. Consider using _vsnprintf_s instead.
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
inline int vsnprintf(char* buf, std::size_t size, const char* format, std::va_list args)
|
||||
{
|
||||
if (BOOST_UNLIKELY(size == 0u))
|
||||
return 0;
|
||||
if (BOOST_UNLIKELY(size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
buf[size - 1u] = '\0';
|
||||
int res = _vsnprintf(buf, size, format, args);
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
// _vsnprintf returns -1 if the output was truncated and in case of other errors.
|
||||
// Detect truncation by checking whether the output buffer was written over entirely.
|
||||
if (buf[size - 1u] != '\0')
|
||||
{
|
||||
buf[size - 1u] = '\0';
|
||||
res = static_cast< int >(size);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int vswprintf(wchar_t* buf, std::size_t size, const wchar_t* format, std::va_list args)
|
||||
{
|
||||
if (BOOST_UNLIKELY(size == 0u || size > static_cast< std::size_t >(INT_MAX)))
|
||||
return -1;
|
||||
|
||||
int res = _vsnwprintf(buf, size, format, args);
|
||||
// (v)swprintf is expected to return -1 on truncation, so we only need to ensure the output is null-terminated
|
||||
if (static_cast< unsigned int >(res) >= size)
|
||||
{
|
||||
buf[size - 1u] = L'\0';
|
||||
res = -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
inline int snprintf(char* buf, std::size_t size, const char* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int res = vsnprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int swprintf(wchar_t* buf, std::size_t size, const wchar_t* format, ...)
|
||||
{
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
int res = vswprintf(buf, size, format, args);
|
||||
va_end(args);
|
||||
return res;
|
||||
}
|
||||
|
||||
#else // defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
// Standard-conforming compilers already have the correct snprintfs
|
||||
using ::snprintf;
|
||||
using ::vsnprintf;
|
||||
|
||||
using ::swprintf;
|
||||
using ::vswprintf;
|
||||
|
||||
#endif // defined(BOOST_CORE_DETAIL_MINGW_SNPRINTF) || defined(BOOST_CORE_DETAIL_MSVC_LEGACY_SNPRINTF)
|
||||
|
||||
} // namespace core
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_CORE_SNPRINTF_HPP_INCLUDED_
|
1181
boost/core/type_name.hpp
Normal file
1181
boost/core/type_name.hpp
Normal file
File diff suppressed because it is too large
Load Diff
43
boost/cregex.hpp
Normal file
43
boost/cregex.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* John Maddock
|
||||
*
|
||||
* Use, modification and distribution are subject to the
|
||||
* Boost Software License, Version 1.0. (See accompanying file
|
||||
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* LOCATION: see http://www.boost.org/libs/regex for most recent version.
|
||||
* FILE cregex.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Declares POSIX API functions
|
||||
* + boost::RegEx high level wrapper.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_RE_CREGEX_HPP
|
||||
#define BOOST_RE_CREGEX_HPP
|
||||
|
||||
#ifndef BOOST_REGEX_CONFIG_HPP
|
||||
#include <boost/regex/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_REGEX_CXX03
|
||||
#include <boost/regex/v4/cregex.hpp>
|
||||
#else
|
||||
#include <boost/regex/v5/cregex.hpp>
|
||||
#endif
|
||||
|
||||
#endif /* include guard */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
50
boost/describe/bases.hpp
Normal file
50
boost/describe/bases.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_BASES_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020, 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/modifiers.hpp>
|
||||
#include <boost/describe/detail/void_t.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class T> using _describe_bases = decltype( boost_base_descriptor_fn( static_cast<T**>(0) ) );
|
||||
|
||||
template<unsigned M> struct base_filter
|
||||
{
|
||||
template<class T> using fn = mp11::mp_bool< ( M & mod_any_access & T::modifiers ) != 0 >;
|
||||
};
|
||||
|
||||
template<class T, class En = void> struct has_describe_bases: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct has_describe_bases<T, void_t<_describe_bases<T>>>: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T, unsigned M> using describe_bases = mp11::mp_copy_if_q<detail::_describe_bases<T>, detail::base_filter<M>>;
|
||||
|
||||
template<class T> using has_describe_bases = detail::has_describe_bases<T>;
|
||||
|
||||
} // namespace describe
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_BASES_HPP_INCLUDED
|
40
boost/describe/detail/config.hpp
Normal file
40
boost/describe/detail/config.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#if __cplusplus >= 201402L
|
||||
|
||||
# define BOOST_DESCRIBE_CXX14
|
||||
# define BOOST_DESCRIBE_CXX11
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
|
||||
# define BOOST_DESCRIBE_CXX14
|
||||
# define BOOST_DESCRIBE_CXX11
|
||||
|
||||
#elif __cplusplus >= 201103L
|
||||
|
||||
# define BOOST_DESCRIBE_CXX11
|
||||
|
||||
# if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 7
|
||||
# undef BOOST_DESCRIBE_CXX11
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST constexpr
|
||||
#else
|
||||
# define BOOST_DESCRIBE_CONSTEXPR_OR_CONST const
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
# define BOOST_DESCRIBE_MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define BOOST_DESCRIBE_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_DETAIL_CONFIG_HPP_INCLUDED
|
30
boost/describe/detail/cx_streq.hpp
Normal file
30
boost/describe/detail/cx_streq.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED
|
||||
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
constexpr bool cx_streq( char const * s1, char const * s2 )
|
||||
{
|
||||
return s1[0] == s2[0] && ( s1[0] == 0 || cx_streq( s1 + 1, s2 + 1 ) );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace describe
|
||||
} // namespace boost
|
||||
|
||||
#endif // defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_DETAIL_CX_STREQ_HPP_INCLUDED
|
32
boost/describe/detail/void_t.hpp
Normal file
32
boost/describe/detail/void_t.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED
|
||||
|
||||
// Copyright 2021 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class...> struct make_void
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
template<class... T> using void_t = typename make_void<T...>::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace describe
|
||||
} // namespace boost
|
||||
|
||||
#endif // defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_DETAIL_VOID_T_HPP_INCLUDED
|
161
boost/describe/members.hpp
Normal file
161
boost/describe/members.hpp
Normal file
@ -0,0 +1,161 @@
|
||||
#ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/modifiers.hpp>
|
||||
#include <boost/describe/bases.hpp>
|
||||
#include <boost/describe/detail/void_t.hpp>
|
||||
#include <boost/describe/detail/cx_streq.hpp>
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
#if defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/bind.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// _describe_members<T>
|
||||
|
||||
template<class T> using _describe_public_members = decltype( boost_public_member_descriptor_fn( static_cast<T**>(0) ) );
|
||||
template<class T> using _describe_protected_members = decltype( boost_protected_member_descriptor_fn( static_cast<T**>(0) ) );
|
||||
template<class T> using _describe_private_members = decltype( boost_private_member_descriptor_fn( static_cast<T**>(0) ) );
|
||||
|
||||
template<class T> using _describe_members = mp11::mp_append<_describe_public_members<T>, _describe_protected_members<T>, _describe_private_members<T>>;
|
||||
|
||||
// describe_inherited_members<T>
|
||||
|
||||
// T: type
|
||||
// V: list of virtual bases visited so far
|
||||
template<class T, class V> struct describe_inherited_members_impl;
|
||||
template<class T, class V> using describe_inherited_members = typename describe_inherited_members_impl<T, V>::type;
|
||||
|
||||
// L: list of base class descriptors
|
||||
// T: derived type
|
||||
// V: list of virtual bases visited so far
|
||||
template<class L, class T, class V> struct describe_inherited_members2_impl;
|
||||
template<class L, class T, class V> using describe_inherited_members2 = typename describe_inherited_members2_impl<L, T, V>::type;
|
||||
|
||||
template<class T, class V> struct describe_inherited_members_impl
|
||||
{
|
||||
using R1 = describe_inherited_members2<describe_bases<T, mod_any_access>, T, V>;
|
||||
using R2 = _describe_members<T>;
|
||||
|
||||
using type = mp11::mp_append<R1, R2>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T, class V> struct describe_inherited_members2_impl<L<>, T, V>
|
||||
{
|
||||
using type = L<>;
|
||||
};
|
||||
|
||||
template<class D1, class D2> using name_matches = mp11::mp_bool< cx_streq( D1::name, D2::name ) >;
|
||||
|
||||
template<class D, class L> using name_is_hidden = mp11::mp_any_of_q<L, mp11::mp_bind_front<name_matches, D>>;
|
||||
|
||||
constexpr unsigned cx_max( unsigned m1, unsigned m2 )
|
||||
{
|
||||
return m1 > m2? m1: m2;
|
||||
}
|
||||
|
||||
template<class T, unsigned Bm> struct update_modifiers
|
||||
{
|
||||
template<class D> struct fn
|
||||
{
|
||||
using L = _describe_members<T>;
|
||||
static constexpr unsigned hidden = name_is_hidden<D, L>::value? mod_hidden: 0;
|
||||
|
||||
static constexpr unsigned mods = D::modifiers;
|
||||
static constexpr unsigned access = cx_max( mods & mod_any_access, Bm & mod_any_access );
|
||||
|
||||
static constexpr decltype(D::pointer) pointer = D::pointer;
|
||||
static constexpr decltype(D::name) name = D::name;
|
||||
static constexpr unsigned modifiers = ( mods & ~mod_any_access ) | access | mod_inherited | hidden;
|
||||
};
|
||||
};
|
||||
|
||||
#ifndef __cpp_inline_variables
|
||||
template<class T, unsigned Bm> template<class D> constexpr decltype(D::pointer) update_modifiers<T, Bm>::fn<D>::pointer;
|
||||
template<class T, unsigned Bm> template<class D> constexpr decltype(D::name) update_modifiers<T, Bm>::fn<D>::name;
|
||||
template<class T, unsigned Bm> template<class D> constexpr unsigned update_modifiers<T, Bm>::fn<D>::modifiers;
|
||||
#endif
|
||||
|
||||
template<class D> struct gather_virtual_bases_impl;
|
||||
template<class D> using gather_virtual_bases = typename gather_virtual_bases_impl<D>::type;
|
||||
|
||||
template<class D> struct gather_virtual_bases_impl
|
||||
{
|
||||
using B = typename D::type;
|
||||
static constexpr unsigned M = D::modifiers;
|
||||
|
||||
using R1 = mp11::mp_transform<gather_virtual_bases, describe_bases<B, mod_any_access>>;
|
||||
using R2 = mp11::mp_apply<mp11::mp_append, R1>;
|
||||
|
||||
using type = mp11::mp_if_c<(M & mod_virtual) != 0, mp11::mp_push_front<R2, B>, R2>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class D1, class... D, class T, class V> struct describe_inherited_members2_impl<L<D1, D...>, T, V>
|
||||
{
|
||||
using B = typename D1::type;
|
||||
static constexpr unsigned M = D1::modifiers;
|
||||
|
||||
using R1 = mp11::mp_if_c<(M & mod_virtual) && mp11::mp_contains<V, B>::value, L<>, describe_inherited_members<B, V>>;
|
||||
|
||||
using R2 = mp11::mp_transform_q<update_modifiers<T, M>, R1>;
|
||||
|
||||
using V2 = mp11::mp_append<V, gather_virtual_bases<D1>>;
|
||||
using R3 = describe_inherited_members2<L<D...>, T, V2>;
|
||||
|
||||
using type = mp11::mp_append<R2, R3>;
|
||||
};
|
||||
|
||||
// describe_members<T, M>
|
||||
|
||||
template<class T, unsigned M> using describe_members = mp11::mp_eval_if_c<(M & mod_inherited) == 0, _describe_members<T>, describe_inherited_members, T, mp11::mp_list<>>;
|
||||
|
||||
// member_filter
|
||||
|
||||
template<unsigned M> struct member_filter
|
||||
{
|
||||
template<class T> using fn = mp11::mp_bool<
|
||||
(M & mod_any_access & T::modifiers) != 0 &&
|
||||
( (M & mod_any_member) != 0 || (M & mod_static) == (T::modifiers & mod_static) ) &&
|
||||
( (M & mod_any_member) != 0 || (M & mod_function) == (T::modifiers & mod_function) ) &&
|
||||
(M & mod_hidden) >= (T::modifiers & mod_hidden)
|
||||
>;
|
||||
};
|
||||
|
||||
// has_describe_members
|
||||
|
||||
template<class T, class En = void> struct has_describe_members: std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template<class T> struct has_describe_members<T, void_t<_describe_members<T>>>: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T, unsigned M> using describe_members = mp11::mp_copy_if_q<detail::describe_members<T, M>, detail::member_filter<M>>;
|
||||
|
||||
template<class T> using has_describe_members = detail::has_describe_members<T>;
|
||||
|
||||
} // namespace describe
|
||||
} // namespace boost
|
||||
|
||||
#endif // !defined(BOOST_DESCRIBE_CXX11)
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_DATA_MEMBERS_HPP_INCLUDED
|
33
boost/describe/modifiers.hpp
Normal file
33
boost/describe/modifiers.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED
|
||||
#define BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/describe/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace describe
|
||||
{
|
||||
|
||||
enum modifiers
|
||||
{
|
||||
mod_public = 1,
|
||||
mod_protected = 2,
|
||||
mod_private = 4,
|
||||
mod_virtual = 8,
|
||||
mod_static = 16,
|
||||
mod_function = 32,
|
||||
mod_any_member = 64,
|
||||
mod_inherited = 128,
|
||||
mod_hidden = 256
|
||||
};
|
||||
|
||||
BOOST_DESCRIBE_CONSTEXPR_OR_CONST modifiers mod_any_access = static_cast<modifiers>( mod_public | mod_protected | mod_private );
|
||||
|
||||
} // namespace describe
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DESCRIBE_MODIFIERS_HPP_INCLUDED
|
262
boost/integer.hpp
Normal file
262
boost/integer.hpp
Normal file
@ -0,0 +1,262 @@
|
||||
// boost integer.hpp header file -------------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes and Daryle Walker 1999. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See https://www.boost.org/libs/integer for documentation.
|
||||
|
||||
// Revision History
|
||||
// 22 Sep 01 Added value-based integer templates. (Daryle Walker)
|
||||
// 01 Apr 01 Modified to use new <boost/limits.hpp> header. (John Maddock)
|
||||
// 30 Jul 00 Add typename syntax fix (Jens Maurer)
|
||||
// 28 Aug 99 Initial version
|
||||
|
||||
#ifndef BOOST_INTEGER_HPP
|
||||
#define BOOST_INTEGER_HPP
|
||||
|
||||
#include <boost/integer_fwd.hpp> // self include
|
||||
|
||||
#include <boost/integer_traits.hpp> // for boost::::boost::integer_traits
|
||||
#include <boost/limits.hpp> // for ::std::numeric_limits
|
||||
#include <boost/cstdint.hpp> // for boost::int64_t and BOOST_NO_INTEGRAL_INT64_T
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
//
|
||||
// We simply cannot include this header on gcc without getting copious warnings of the kind:
|
||||
//
|
||||
// boost/integer.hpp:77:30: warning: use of C99 long long integer constant
|
||||
//
|
||||
// And yet there is no other reasonable implementation, so we declare this a system header
|
||||
// to suppress these warnings.
|
||||
//
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
// Helper templates ------------------------------------------------------//
|
||||
|
||||
// fast integers from least integers
|
||||
// int_fast_t<> works correctly for unsigned too, in spite of the name.
|
||||
template< typename LeastInt >
|
||||
struct int_fast_t
|
||||
{
|
||||
typedef LeastInt fast;
|
||||
typedef fast type;
|
||||
}; // imps may specialize
|
||||
|
||||
namespace detail{
|
||||
|
||||
// convert category to type
|
||||
template< int Category > struct int_least_helper {}; // default is empty
|
||||
template< int Category > struct uint_least_helper {}; // default is empty
|
||||
|
||||
// specializatons: 1=long, 2=int, 3=short, 4=signed char,
|
||||
// 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char
|
||||
// no specializations for 0 and 5: requests for a type > long are in error
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template<> struct int_least_helper<1> { typedef boost::long_long_type least; };
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
template<> struct int_least_helper<1> { typedef __int64 least; };
|
||||
#endif
|
||||
template<> struct int_least_helper<2> { typedef long least; };
|
||||
template<> struct int_least_helper<3> { typedef int least; };
|
||||
template<> struct int_least_helper<4> { typedef short least; };
|
||||
template<> struct int_least_helper<5> { typedef signed char least; };
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
template<> struct uint_least_helper<1> { typedef boost::ulong_long_type least; };
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
template<> struct uint_least_helper<1> { typedef unsigned __int64 least; };
|
||||
#endif
|
||||
template<> struct uint_least_helper<2> { typedef unsigned long least; };
|
||||
template<> struct uint_least_helper<3> { typedef unsigned int least; };
|
||||
template<> struct uint_least_helper<4> { typedef unsigned short least; };
|
||||
template<> struct uint_least_helper<5> { typedef unsigned char least; };
|
||||
|
||||
template <int Bits>
|
||||
struct exact_signed_base_helper{};
|
||||
template <int Bits>
|
||||
struct exact_unsigned_base_helper{};
|
||||
|
||||
template <> struct exact_signed_base_helper<sizeof(signed char)* CHAR_BIT> { typedef signed char exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned char)* CHAR_BIT> { typedef unsigned char exact; };
|
||||
#if USHRT_MAX != UCHAR_MAX
|
||||
template <> struct exact_signed_base_helper<sizeof(short)* CHAR_BIT> { typedef short exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned short)* CHAR_BIT> { typedef unsigned short exact; };
|
||||
#endif
|
||||
#if UINT_MAX != USHRT_MAX
|
||||
template <> struct exact_signed_base_helper<sizeof(int)* CHAR_BIT> { typedef int exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned int)* CHAR_BIT> { typedef unsigned int exact; };
|
||||
#endif
|
||||
#if ULONG_MAX != UINT_MAX && ( !defined __TI_COMPILER_VERSION__ || \
|
||||
( __TI_COMPILER_VERSION__ >= 7000000 && !defined __TI_40BIT_LONG__ ) )
|
||||
template <> struct exact_signed_base_helper<sizeof(long)* CHAR_BIT> { typedef long exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(unsigned long)* CHAR_BIT> { typedef unsigned long exact; };
|
||||
#endif
|
||||
#if defined(BOOST_HAS_LONG_LONG) &&\
|
||||
((defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) ||\
|
||||
(defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) ||\
|
||||
(defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) ||\
|
||||
(defined(_ULLONG_MAX) && (_ULLONG_MAX != ULONG_MAX)))
|
||||
template <> struct exact_signed_base_helper<sizeof(boost::long_long_type)* CHAR_BIT> { typedef boost::long_long_type exact; };
|
||||
template <> struct exact_unsigned_base_helper<sizeof(boost::ulong_long_type)* CHAR_BIT> { typedef boost::ulong_long_type exact; };
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// integer templates specifying number of bits ---------------------------//
|
||||
|
||||
// signed
|
||||
template< int Bits > // bits (including sign) required
|
||||
struct int_t : public boost::detail::exact_signed_base_helper<Bits>
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::intmax_t) * CHAR_BIT),
|
||||
"No suitable signed integer type with the requested number of bits is available.");
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
(Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
|
||||
#else
|
||||
1 +
|
||||
#endif
|
||||
(Bits-1 <= ::std::numeric_limits<long>::digits) +
|
||||
(Bits-1 <= ::std::numeric_limits<int>::digits) +
|
||||
(Bits-1 <= ::std::numeric_limits<short>::digits) +
|
||||
(Bits-1 <= ::std::numeric_limits<signed char>::digits)
|
||||
>::least least;
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
};
|
||||
|
||||
// unsigned
|
||||
template< int Bits > // bits required
|
||||
struct uint_t : public boost::detail::exact_unsigned_base_helper<Bits>
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::uintmax_t) * CHAR_BIT),
|
||||
"No suitable unsigned integer type with the requested number of bits is available.");
|
||||
#if (defined(BOOST_BORLANDC) || defined(__CODEGEAR__)) && defined(BOOST_NO_INTEGRAL_INT64_T)
|
||||
// It's really not clear why this workaround should be needed... shrug I guess! JM
|
||||
BOOST_STATIC_CONSTANT(int, s =
|
||||
6 +
|
||||
(Bits <= ::std::numeric_limits<unsigned long>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned int>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned short>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned char>::digits));
|
||||
typedef typename detail::int_least_helper< ::boost::uint_t<Bits>::s>::least least;
|
||||
#else
|
||||
typedef typename boost::detail::uint_least_helper
|
||||
<
|
||||
#ifdef BOOST_HAS_LONG_LONG
|
||||
(Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
|
||||
#else
|
||||
1 +
|
||||
#endif
|
||||
(Bits <= ::std::numeric_limits<unsigned long>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned int>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned short>::digits) +
|
||||
(Bits <= ::std::numeric_limits<unsigned char>::digits)
|
||||
>::least least;
|
||||
#endif
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
// int_fast_t<> works correctly for unsigned too, in spite of the name.
|
||||
};
|
||||
|
||||
// integer templates specifying extreme value ----------------------------//
|
||||
|
||||
// signed
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
template< boost::long_long_type MaxValue > // maximum value to require support
|
||||
#else
|
||||
template< long MaxValue > // maximum value to require support
|
||||
#endif
|
||||
struct int_max_value_t
|
||||
{
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MaxValue <= ::boost::integer_traits<boost::long_long_type>::const_max) +
|
||||
#else
|
||||
1 +
|
||||
#endif
|
||||
(MaxValue <= ::boost::integer_traits<long>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<int>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<short>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<signed char>::const_max)
|
||||
>::least least;
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
template< boost::long_long_type MinValue > // minimum value to require support
|
||||
#else
|
||||
template< long MinValue > // minimum value to require support
|
||||
#endif
|
||||
struct int_min_value_t
|
||||
{
|
||||
typedef typename boost::detail::int_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MinValue >= ::boost::integer_traits<boost::long_long_type>::const_min) +
|
||||
#else
|
||||
1 +
|
||||
#endif
|
||||
(MinValue >= ::boost::integer_traits<long>::const_min) +
|
||||
(MinValue >= ::boost::integer_traits<int>::const_min) +
|
||||
(MinValue >= ::boost::integer_traits<short>::const_min) +
|
||||
(MinValue >= ::boost::integer_traits<signed char>::const_min)
|
||||
>::least least;
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
};
|
||||
|
||||
// unsigned
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
template< boost::ulong_long_type MaxValue > // minimum value to require support
|
||||
#else
|
||||
template< unsigned long MaxValue > // minimum value to require support
|
||||
#endif
|
||||
struct uint_value_t
|
||||
{
|
||||
#if (defined(BOOST_BORLANDC) || defined(__CODEGEAR__))
|
||||
// It's really not clear why this workaround should be needed... shrug I guess! JM
|
||||
#if defined(BOOST_NO_INTEGRAL_INT64_T)
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
1 +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned char>::const_max));
|
||||
typedef typename detail::int_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
|
||||
#else // BOOST_NO_INTEGRAL_INT64_T
|
||||
BOOST_STATIC_CONSTANT(unsigned, which =
|
||||
1 +
|
||||
(MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned char>::const_max));
|
||||
typedef typename detail::uint_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
|
||||
#endif // BOOST_NO_INTEGRAL_INT64_T
|
||||
#else
|
||||
typedef typename boost::detail::uint_least_helper
|
||||
<
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
|
||||
(MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
|
||||
#else
|
||||
1 +
|
||||
#endif
|
||||
(MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
|
||||
(MaxValue <= ::boost::integer_traits<unsigned char>::const_max)
|
||||
>::least least;
|
||||
#endif
|
||||
typedef typename int_fast_t<least>::type fast;
|
||||
};
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_INTEGER_HPP
|
256
boost/integer_traits.hpp
Normal file
256
boost/integer_traits.hpp
Normal file
@ -0,0 +1,256 @@
|
||||
/* boost integer_traits.hpp header file
|
||||
*
|
||||
* Copyright Jens Maurer 2000
|
||||
* Distributed under the Boost Software License, Version 1.0. (See
|
||||
* accompanying file LICENSE_1_0.txt or copy at
|
||||
* https://www.boost.org/LICENSE_1_0.txt)
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers
|
||||
*/
|
||||
|
||||
// See https://www.boost.org/libs/integer for documentation.
|
||||
|
||||
|
||||
#ifndef BOOST_INTEGER_TRAITS_HPP
|
||||
#define BOOST_INTEGER_TRAITS_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/limits.hpp>
|
||||
|
||||
// These are an implementation detail and not part of the interface
|
||||
#include <limits.h>
|
||||
// we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it,
|
||||
// and some may have <wchar.h> but not <cwchar> ...
|
||||
#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__))
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
//
|
||||
// We simply cannot include this header on gcc without getting copious warnings of the kind:
|
||||
//
|
||||
// ../../../boost/integer_traits.hpp:164:66: warning: use of C99 long long integer constant
|
||||
//
|
||||
// And yet there is no other reasonable implementation, so we declare this a system header
|
||||
// to suppress these warnings.
|
||||
//
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<class T>
|
||||
class integer_traits : public std::numeric_limits<T>
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, is_integral = false);
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<class T, T min_val, T max_val>
|
||||
class integer_traits_base
|
||||
{
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, is_integral = true);
|
||||
BOOST_STATIC_CONSTANT(T, const_min = min_val);
|
||||
BOOST_STATIC_CONSTANT(T, const_max = max_val);
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
// A definition is required even for integral static constants
|
||||
template<class T, T min_val, T max_val>
|
||||
const bool integer_traits_base<T, min_val, max_val>::is_integral;
|
||||
|
||||
template<class T, T min_val, T max_val>
|
||||
const T integer_traits_base<T, min_val, max_val>::const_min;
|
||||
|
||||
template<class T, T min_val, T max_val>
|
||||
const T integer_traits_base<T, min_val, max_val>::const_max;
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<>
|
||||
class integer_traits<bool>
|
||||
: public std::numeric_limits<bool>,
|
||||
public detail::integer_traits_base<bool, false, true>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<char>
|
||||
: public std::numeric_limits<char>,
|
||||
public detail::integer_traits_base<char, CHAR_MIN, CHAR_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<signed char>
|
||||
: public std::numeric_limits<signed char>,
|
||||
public detail::integer_traits_base<signed char, SCHAR_MIN, SCHAR_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<unsigned char>
|
||||
: public std::numeric_limits<unsigned char>,
|
||||
public detail::integer_traits_base<unsigned char, 0, UCHAR_MAX>
|
||||
{ };
|
||||
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
||||
template<>
|
||||
class integer_traits<wchar_t>
|
||||
: public std::numeric_limits<wchar_t>,
|
||||
// Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native
|
||||
// library: they are wrong!
|
||||
#if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__)
|
||||
public detail::integer_traits_base<wchar_t, WCHAR_MIN, WCHAR_MAX>
|
||||
#elif defined(BOOST_BORLANDC) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__))
|
||||
// No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned:
|
||||
public detail::integer_traits_base<wchar_t, 0, 0xffff>
|
||||
#elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\
|
||||
|| (defined __APPLE__)\
|
||||
|| (defined(__OpenBSD__) && defined(__GNUC__))\
|
||||
|| (defined(__NetBSD__) && defined(__GNUC__))\
|
||||
|| (defined(__FreeBSD__) && defined(__GNUC__))\
|
||||
|| (defined(__DragonFly__) && defined(__GNUC__))\
|
||||
|| (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT))
|
||||
// No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int.
|
||||
// - SGI MIPSpro with native library
|
||||
// - gcc 3.x on HP-UX
|
||||
// - Mac OS X with native library
|
||||
// - gcc on FreeBSD, OpenBSD and NetBSD
|
||||
public detail::integer_traits_base<wchar_t, INT_MIN, INT_MAX>
|
||||
#else
|
||||
#error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler.
|
||||
#endif
|
||||
{ };
|
||||
#endif // BOOST_NO_INTRINSIC_WCHAR_T
|
||||
|
||||
template<>
|
||||
class integer_traits<short>
|
||||
: public std::numeric_limits<short>,
|
||||
public detail::integer_traits_base<short, SHRT_MIN, SHRT_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<unsigned short>
|
||||
: public std::numeric_limits<unsigned short>,
|
||||
public detail::integer_traits_base<unsigned short, 0, USHRT_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<int>
|
||||
: public std::numeric_limits<int>,
|
||||
public detail::integer_traits_base<int, INT_MIN, INT_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<unsigned int>
|
||||
: public std::numeric_limits<unsigned int>,
|
||||
public detail::integer_traits_base<unsigned int, 0, UINT_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<long>
|
||||
: public std::numeric_limits<long>,
|
||||
public detail::integer_traits_base<long, LONG_MIN, LONG_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits<unsigned long>
|
||||
: public std::numeric_limits<unsigned long>,
|
||||
public detail::integer_traits_base<unsigned long, 0, ULONG_MAX>
|
||||
{ };
|
||||
|
||||
#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T)
|
||||
#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::long_long_type>
|
||||
: public std::numeric_limits< ::boost::long_long_type>,
|
||||
public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::ulong_long_type>
|
||||
: public std::numeric_limits< ::boost::ulong_long_type>,
|
||||
public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX>
|
||||
{ };
|
||||
|
||||
#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ };
|
||||
template<>
|
||||
class integer_traits< ::boost::ulong_long_type>
|
||||
: public std::numeric_limits< ::boost::ulong_long_type>,
|
||||
public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX>
|
||||
{ };
|
||||
|
||||
#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::long_long_type>
|
||||
: public std::numeric_limits< ::boost::long_long_type>,
|
||||
public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::ulong_long_type>
|
||||
: public std::numeric_limits< ::boost::ulong_long_type>,
|
||||
public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX>
|
||||
{ };
|
||||
|
||||
#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG)
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::long_long_type>
|
||||
: public std::numeric_limits< ::boost::long_long_type>,
|
||||
public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::ulong_long_type>
|
||||
: public std::numeric_limits< ::boost::ulong_long_type>,
|
||||
public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX>
|
||||
{ };
|
||||
|
||||
#elif defined(BOOST_HAS_LONG_LONG)
|
||||
//
|
||||
// we have long long but no constants, this happens for example with gcc in -ansi mode,
|
||||
// we'll just have to work out the values for ourselves (assumes 2's compliment representation):
|
||||
//
|
||||
template<>
|
||||
class integer_traits< ::boost::long_long_type>
|
||||
: public std::numeric_limits< ::boost::long_long_type>,
|
||||
public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits< ::boost::ulong_long_type>
|
||||
: public std::numeric_limits< ::boost::ulong_long_type>,
|
||||
public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL>
|
||||
{ };
|
||||
|
||||
#elif defined(BOOST_HAS_MS_INT64)
|
||||
|
||||
template<>
|
||||
class integer_traits< __int64>
|
||||
: public std::numeric_limits< __int64>,
|
||||
public detail::integer_traits_base< __int64, _I64_MIN, _I64_MAX>
|
||||
{ };
|
||||
|
||||
template<>
|
||||
class integer_traits< unsigned __int64>
|
||||
: public std::numeric_limits< unsigned __int64>,
|
||||
public detail::integer_traits_base< unsigned __int64, 0, _UI64_MAX>
|
||||
{ };
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif /* BOOST_INTEGER_TRAITS_HPP */
|
||||
|
||||
|
||||
|
39
boost/io/detail/buffer_fill.hpp
Normal file
39
boost/io/detail/buffer_fill.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2019-2020 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_DETAIL_BUFFER_FILL_HPP
|
||||
#define BOOST_IO_DETAIL_BUFFER_FILL_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline bool
|
||||
buffer_fill(std::basic_streambuf<charT, traits>& buf, charT ch,
|
||||
std::size_t size)
|
||||
{
|
||||
charT fill[] = { ch, ch, ch, ch, ch, ch, ch, ch };
|
||||
enum {
|
||||
chunk = sizeof fill / sizeof(charT)
|
||||
};
|
||||
for (; size > chunk; size -= chunk) {
|
||||
if (static_cast<std::size_t>(buf.sputn(fill, chunk)) != chunk) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return static_cast<std::size_t>(buf.sputn(fill, size)) == size;
|
||||
}
|
||||
|
||||
} /* detail */
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
45
boost/io/detail/ostream_guard.hpp
Normal file
45
boost/io/detail/ostream_guard.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2019-2020 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_DETAIL_OSTREAM_GUARD_HPP
|
||||
#define BOOST_IO_DETAIL_OSTREAM_GUARD_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
namespace detail {
|
||||
|
||||
template<class Char, class Traits>
|
||||
class ostream_guard {
|
||||
public:
|
||||
explicit ostream_guard(std::basic_ostream<Char, Traits>& os) BOOST_NOEXCEPT
|
||||
: os_(&os) { }
|
||||
|
||||
~ostream_guard() BOOST_NOEXCEPT_IF(false) {
|
||||
if (os_) {
|
||||
os_->setstate(std::basic_ostream<Char, Traits>::badbit);
|
||||
}
|
||||
}
|
||||
|
||||
void release() BOOST_NOEXCEPT {
|
||||
os_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
ostream_guard(const ostream_guard&);
|
||||
ostream_guard& operator=(const ostream_guard&);
|
||||
|
||||
std::basic_ostream<Char, Traits>* os_;
|
||||
};
|
||||
|
||||
} /* detail */
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
50
boost/io/ostream_put.hpp
Normal file
50
boost/io/ostream_put.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2019 Glen Joseph Fernandes
|
||||
(glenjofe@gmail.com)
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
#ifndef BOOST_IO_OSTREAM_PUT_HPP
|
||||
#define BOOST_IO_OSTREAM_PUT_HPP
|
||||
|
||||
#include <boost/io/detail/buffer_fill.hpp>
|
||||
#include <boost/io/detail/ostream_guard.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace io {
|
||||
|
||||
template<class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>&
|
||||
ostream_put(std::basic_ostream<charT, traits>& os, const charT* data,
|
||||
std::size_t size)
|
||||
{
|
||||
typedef std::basic_ostream<charT, traits> stream;
|
||||
detail::ostream_guard<charT, traits> guard(os);
|
||||
typename stream::sentry entry(os);
|
||||
if (entry) {
|
||||
std::basic_streambuf<charT, traits>& buf = *os.rdbuf();
|
||||
std::size_t width = static_cast<std::size_t>(os.width());
|
||||
if (width <= size) {
|
||||
if (static_cast<std::size_t>(buf.sputn(data, size)) != size) {
|
||||
return os;
|
||||
}
|
||||
} else if ((os.flags() & stream::adjustfield) == stream::left) {
|
||||
if (static_cast<std::size_t>(buf.sputn(data, size)) != size ||
|
||||
!detail::buffer_fill(buf, os.fill(), width - size)) {
|
||||
return os;
|
||||
}
|
||||
} else if (!detail::buffer_fill(buf, os.fill(), width - size) ||
|
||||
static_cast<std::size_t>(buf.sputn(data, size)) != size) {
|
||||
return os;
|
||||
}
|
||||
os.width(0);
|
||||
}
|
||||
guard.release();
|
||||
return os;
|
||||
}
|
||||
|
||||
} /* io */
|
||||
} /* boost */
|
||||
|
||||
#endif
|
254
boost/iterator/counting_iterator.hpp
Normal file
254
boost/iterator/counting_iterator.hpp
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright David Abrahams 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef COUNTING_ITERATOR_DWA200348_HPP
|
||||
# define COUNTING_ITERATOR_DWA200348_HPP
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
# include <limits>
|
||||
# elif !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# else
|
||||
# include <boost/type_traits/is_arithmetic.hpp>
|
||||
# endif
|
||||
# include <boost/type_traits/is_integral.hpp>
|
||||
# include <boost/type_traits/type_identity.hpp>
|
||||
# include <boost/type_traits/conditional.hpp>
|
||||
# include <boost/type_traits/integral_constant.hpp>
|
||||
# include <boost/detail/numeric_traits.hpp>
|
||||
# include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal
|
||||
, class Difference
|
||||
>
|
||||
class counting_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Try to detect numeric types at compile time in ways compatible
|
||||
// with the limitations of the compiler and library.
|
||||
template <class T>
|
||||
struct is_numeric_impl
|
||||
{
|
||||
// For a while, this wasn't true, but we rely on it below. This is a regression assert.
|
||||
BOOST_STATIC_ASSERT(::boost::is_integral<char>::value);
|
||||
|
||||
# ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<T>::is_specialized);
|
||||
|
||||
# else
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551))
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
boost::is_convertible<int,T>::value
|
||||
&& boost::is_convertible<T,int>::value
|
||||
));
|
||||
# else
|
||||
BOOST_STATIC_CONSTANT(bool, value = ::boost::is_arithmetic<T>::value);
|
||||
# endif
|
||||
|
||||
# endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_numeric
|
||||
: boost::integral_constant<bool, ::boost::iterators::detail::is_numeric_impl<T>::value>
|
||||
{};
|
||||
|
||||
# if defined(BOOST_HAS_LONG_LONG)
|
||||
template <>
|
||||
struct is_numeric<boost::long_long_type>
|
||||
: boost::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_numeric<boost::ulong_long_type>
|
||||
: boost::true_type {};
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_HAS_INT128)
|
||||
template <>
|
||||
struct is_numeric<boost::int128_type>
|
||||
: boost::true_type {};
|
||||
|
||||
template <>
|
||||
struct is_numeric<boost::uint128_type>
|
||||
: boost::true_type {};
|
||||
# endif
|
||||
|
||||
// Some compilers fail to have a numeric_limits specialization
|
||||
template <>
|
||||
struct is_numeric<wchar_t>
|
||||
: true_type {};
|
||||
|
||||
template <class T>
|
||||
struct numeric_difference
|
||||
{
|
||||
typedef typename boost::detail::numeric_traits<T>::difference_type type;
|
||||
};
|
||||
|
||||
# if defined(BOOST_HAS_INT128)
|
||||
// std::numeric_limits, which is used by numeric_traits, is not specialized for __int128 in some standard libraries
|
||||
template <>
|
||||
struct numeric_difference<boost::int128_type>
|
||||
{
|
||||
typedef boost::int128_type type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct numeric_difference<boost::uint128_type>
|
||||
{
|
||||
typedef boost::int128_type type;
|
||||
};
|
||||
# endif
|
||||
|
||||
template <class Incrementable, class CategoryOrTraversal, class Difference>
|
||||
struct counting_iterator_base
|
||||
{
|
||||
typedef typename detail::ia_dflt_help<
|
||||
CategoryOrTraversal
|
||||
, typename boost::conditional<
|
||||
is_numeric<Incrementable>::value
|
||||
, boost::type_identity<random_access_traversal_tag>
|
||||
, iterator_traversal<Incrementable>
|
||||
>::type
|
||||
>::type traversal;
|
||||
|
||||
typedef typename detail::ia_dflt_help<
|
||||
Difference
|
||||
, typename boost::conditional<
|
||||
is_numeric<Incrementable>::value
|
||||
, numeric_difference<Incrementable>
|
||||
, iterator_difference<Incrementable>
|
||||
>::type
|
||||
>::type difference;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
counting_iterator<Incrementable, CategoryOrTraversal, Difference> // self
|
||||
, Incrementable // Base
|
||||
, Incrementable // Value
|
||||
# ifndef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
|
||||
const // MSVC won't strip this. Instead we enable Thomas'
|
||||
// criterion (see boost/iterator/detail/facade_iterator_category.hpp)
|
||||
# endif
|
||||
, traversal
|
||||
, Incrementable const& // reference
|
||||
, difference
|
||||
> type;
|
||||
};
|
||||
|
||||
// Template class distance_policy_select -- choose a policy for computing the
|
||||
// distance between counting_iterators at compile-time based on whether or not
|
||||
// the iterator wraps an integer or an iterator, using "poor man's partial
|
||||
// specialization".
|
||||
|
||||
template <bool is_integer> struct distance_policy_select;
|
||||
|
||||
// A policy for wrapped iterators
|
||||
template <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct iterator_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return y - x;
|
||||
}
|
||||
};
|
||||
|
||||
// A policy for wrapped numbers
|
||||
template <class Difference, class Incrementable1, class Incrementable2>
|
||||
struct number_distance
|
||||
{
|
||||
static Difference distance(Incrementable1 x, Incrementable2 y)
|
||||
{
|
||||
return boost::detail::numeric_distance(x, y);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
class Incrementable
|
||||
, class CategoryOrTraversal = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class counting_iterator
|
||||
: public detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::counting_iterator_base<
|
||||
Incrementable, CategoryOrTraversal, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
typedef typename super_t::difference_type difference_type;
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(counting_iterator(), {})
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(counting_iterator(counting_iterator const& rhs), : super_t(rhs.base()) {})
|
||||
|
||||
counting_iterator(Incrementable x)
|
||||
: super_t(x)
|
||||
{
|
||||
}
|
||||
|
||||
# if 0
|
||||
template<class OtherIncrementable>
|
||||
counting_iterator(
|
||||
counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& t
|
||||
, typename enable_if_convertible<OtherIncrementable, Incrementable>::type* = 0
|
||||
)
|
||||
: super_t(t.base())
|
||||
{}
|
||||
# endif
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(counting_iterator& operator=(counting_iterator const& rhs), { *static_cast< super_t* >(this) = static_cast< super_t const& >(rhs); return *this; })
|
||||
|
||||
private:
|
||||
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
return this->base_reference();
|
||||
}
|
||||
|
||||
template <class OtherIncrementable>
|
||||
difference_type
|
||||
distance_to(counting_iterator<OtherIncrementable, CategoryOrTraversal, Difference> const& y) const
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
detail::is_numeric<Incrementable>::value
|
||||
, detail::number_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
, detail::iterator_distance<difference_type, Incrementable, OtherIncrementable>
|
||||
>::type d;
|
||||
|
||||
return d::distance(this->base(), y.base());
|
||||
}
|
||||
};
|
||||
|
||||
// Manufacture a counting iterator for an arbitrary incrementable type
|
||||
template <class Incrementable>
|
||||
inline counting_iterator<Incrementable>
|
||||
make_counting_iterator(Incrementable x)
|
||||
{
|
||||
typedef counting_iterator<Incrementable> result_t;
|
||||
return result_t(x);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::counting_iterator;
|
||||
using iterators::make_counting_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // COUNTING_ITERATOR_DWA200348_HPP
|
21
boost/iterator/detail/any_conversion_eater.hpp
Normal file
21
boost/iterator/detail/any_conversion_eater.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
# define ANY_CONVERSION_EATER_DWA20031117_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
// This type can be used in traits to "eat" up the one user-defined
|
||||
// implicit conversion allowed.
|
||||
struct any_conversion_eater
|
||||
{
|
||||
template <class T>
|
||||
any_conversion_eater(T const&);
|
||||
};
|
||||
|
||||
}}} // namespace boost::iterators::detail
|
||||
|
||||
#endif // ANY_CONVERSION_EATER_DWA20031117_HPP
|
19
boost/iterator/detail/minimum_category.hpp
Normal file
19
boost/iterator/detail/minimum_category.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
# define MINIMUM_CATEGORY_DWA20031119_HPP
|
||||
|
||||
# include <boost/iterator/minimum_category.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// This import below (as well as the whole header) is for backward compatibility
|
||||
// with boost/token_iterator.hpp. It should be removed as soon as that header is fixed.
|
||||
namespace detail {
|
||||
using iterators::minimum_category;
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // MINIMUM_CATEGORY_DWA20031119_HPP
|
146
boost/iterator/filter_iterator.hpp
Normal file
146
boost/iterator/filter_iterator.hpp
Normal file
@ -0,0 +1,146 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_FILTER_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#define BOOST_ITERATOR_DETAIL_MOVE(_type, _value) static_cast< _type&& >(_value)
|
||||
#else
|
||||
#define BOOST_ITERATOR_DETAIL_MOVE(_type, _value) _value
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Predicate, class Iterator>
|
||||
struct filter_iterator_base
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
filter_iterator<Predicate, Iterator>
|
||||
, Iterator
|
||||
, use_default
|
||||
, typename mpl::if_<
|
||||
is_convertible<
|
||||
typename iterator_traversal<Iterator>::type
|
||||
, random_access_traversal_tag
|
||||
>
|
||||
, bidirectional_traversal_tag
|
||||
, use_default
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
class filter_iterator
|
||||
: public detail::filter_iterator_base<Predicate, Iterator>::type
|
||||
{
|
||||
typedef typename detail::filter_iterator_base<
|
||||
Predicate, Iterator
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
filter_iterator() { }
|
||||
|
||||
filter_iterator(Predicate f, Iterator x, Iterator end_ = Iterator())
|
||||
: super_t(BOOST_ITERATOR_DETAIL_MOVE(Iterator, x)), m_predicate(BOOST_ITERATOR_DETAIL_MOVE(Predicate, f)), m_end(BOOST_ITERATOR_DETAIL_MOVE(Iterator, end_))
|
||||
{
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
filter_iterator(Iterator x, Iterator end_ = Iterator())
|
||||
: super_t(BOOST_ITERATOR_DETAIL_MOVE(Iterator, x)), m_predicate(), m_end(BOOST_ITERATOR_DETAIL_MOVE(Iterator, end_))
|
||||
{
|
||||
// Pro8 is a little too aggressive about instantiating the
|
||||
// body of this function.
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
// Don't allow use of this constructor if Predicate is a
|
||||
// function pointer type, since it will be 0.
|
||||
BOOST_STATIC_ASSERT(is_class<Predicate>::value);
|
||||
#endif
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
template<class OtherIterator>
|
||||
filter_iterator(
|
||||
filter_iterator<Predicate, OtherIterator> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||
)
|
||||
: super_t(t.base()), m_predicate(t.predicate()), m_end(t.end()) {}
|
||||
|
||||
Predicate predicate() const { return m_predicate; }
|
||||
|
||||
Iterator end() const { return m_end; }
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
++(this->base_reference());
|
||||
satisfy_predicate();
|
||||
}
|
||||
|
||||
void decrement()
|
||||
{
|
||||
while(!this->m_predicate(*--(this->base_reference()))){};
|
||||
}
|
||||
|
||||
void satisfy_predicate()
|
||||
{
|
||||
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
|
||||
++(this->base_reference());
|
||||
}
|
||||
|
||||
// Probably should be the initial base class so it can be
|
||||
// optimized away via EBO if it is an empty class.
|
||||
Predicate m_predicate;
|
||||
Iterator m_end;
|
||||
};
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
inline filter_iterator<Predicate,Iterator>
|
||||
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator())
|
||||
{
|
||||
return filter_iterator<Predicate,Iterator>(BOOST_ITERATOR_DETAIL_MOVE(Predicate, f), BOOST_ITERATOR_DETAIL_MOVE(Iterator, x), BOOST_ITERATOR_DETAIL_MOVE(Iterator, end));
|
||||
}
|
||||
|
||||
template <class Predicate, class Iterator>
|
||||
inline filter_iterator<Predicate,Iterator>
|
||||
make_filter_iterator(
|
||||
typename iterators::enable_if<
|
||||
is_class<Predicate>
|
||||
, Iterator
|
||||
>::type x
|
||||
, Iterator end = Iterator())
|
||||
{
|
||||
return filter_iterator<Predicate,Iterator>(BOOST_ITERATOR_DETAIL_MOVE(Iterator, x), BOOST_ITERATOR_DETAIL_MOVE(Iterator, end));
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::filter_iterator;
|
||||
using iterators::make_filter_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_ITERATOR_DETAIL_MOVE
|
||||
|
||||
#endif // BOOST_FILTER_ITERATOR_23022003THW_HPP
|
180
boost/iterator/function_input_iterator.hpp
Normal file
180
boost/iterator/function_input_iterator.hpp
Normal file
@ -0,0 +1,180 @@
|
||||
// Copyright 2009 (C) Dean Michael Berris <me@deanberris.com>
|
||||
// Copyright 2012 (C) Google, Inc.
|
||||
// Copyright 2012 (C) Jeffrey Lee Hellrung, Jr.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BOOST_FUNCTION_INPUT_ITERATOR
|
||||
#define BOOST_FUNCTION_INPUT_ITERATOR
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
#include <boost/function_types/is_function_pointer.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/none.hpp>
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
#ifdef BOOST_RESULT_OF_USE_TR1
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace iterators {
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_input_iterator;
|
||||
|
||||
namespace impl {
|
||||
|
||||
// Computes the return type of an lvalue-call with an empty argument,
|
||||
// i.e. decltype(declval<F&>()()). F should be a nullary lvalue-callable
|
||||
// or function.
|
||||
template <class F>
|
||||
struct result_of_nullary_lvalue_call
|
||||
{
|
||||
typedef typename result_of<
|
||||
#ifdef BOOST_RESULT_OF_USE_TR1
|
||||
typename boost::conditional<is_function<F>::value, F&, F>::type()
|
||||
#else
|
||||
F&()
|
||||
#endif
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_object_input_iterator :
|
||||
public iterator_facade<
|
||||
iterators::function_input_iterator<Function, Input>,
|
||||
typename result_of_nullary_lvalue_call<Function>::type,
|
||||
single_pass_traversal_tag,
|
||||
typename result_of_nullary_lvalue_call<Function>::type const &
|
||||
>
|
||||
{
|
||||
public:
|
||||
function_object_input_iterator() {}
|
||||
function_object_input_iterator(Function & f_, Input state_ = Input())
|
||||
: f(boost::addressof(f_)), state(state_) {}
|
||||
|
||||
void increment() {
|
||||
if (value)
|
||||
value = none;
|
||||
else
|
||||
(*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename result_of_nullary_lvalue_call<Function>::type const &
|
||||
dereference() const {
|
||||
if (!value)
|
||||
value = (*f)();
|
||||
return value.get();
|
||||
}
|
||||
|
||||
bool equal(function_object_input_iterator const & other) const {
|
||||
return f == other.f && state == other.state;
|
||||
}
|
||||
|
||||
private:
|
||||
Function * f;
|
||||
Input state;
|
||||
mutable optional<typename result_of_nullary_lvalue_call<Function>::type> value;
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_pointer_input_iterator :
|
||||
public iterator_facade<
|
||||
iterators::function_input_iterator<Function, Input>,
|
||||
typename function_types::result_type<Function>::type,
|
||||
single_pass_traversal_tag,
|
||||
typename function_types::result_type<Function>::type const &
|
||||
>
|
||||
{
|
||||
public:
|
||||
function_pointer_input_iterator() {}
|
||||
function_pointer_input_iterator(Function &f_, Input state_ = Input())
|
||||
: f(f_), state(state_) {}
|
||||
|
||||
void increment() {
|
||||
if (value)
|
||||
value = none;
|
||||
else
|
||||
(*f)();
|
||||
++state;
|
||||
}
|
||||
|
||||
typename function_types::result_type<Function>::type const &
|
||||
dereference() const {
|
||||
if (!value)
|
||||
value = (*f)();
|
||||
return value.get();
|
||||
}
|
||||
|
||||
bool equal(function_pointer_input_iterator const & other) const {
|
||||
return f == other.f && state == other.state;
|
||||
}
|
||||
|
||||
private:
|
||||
Function f;
|
||||
Input state;
|
||||
mutable optional<typename function_types::result_type<Function>::type> value;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template <class Function, class Input>
|
||||
class function_input_iterator :
|
||||
public boost::conditional<
|
||||
function_types::is_function_pointer<Function>::value,
|
||||
impl::function_pointer_input_iterator<Function,Input>,
|
||||
impl::function_object_input_iterator<Function,Input>
|
||||
>::type
|
||||
{
|
||||
typedef typename boost::conditional<
|
||||
function_types::is_function_pointer<Function>::value,
|
||||
impl::function_pointer_input_iterator<Function,Input>,
|
||||
impl::function_object_input_iterator<Function,Input>
|
||||
>::type base_type;
|
||||
public:
|
||||
function_input_iterator(Function & f, Input i)
|
||||
: base_type(f, i) {}
|
||||
};
|
||||
|
||||
template <class Function, class Input>
|
||||
inline function_input_iterator<Function, Input>
|
||||
make_function_input_iterator(Function & f, Input state) {
|
||||
typedef function_input_iterator<Function, Input> result_t;
|
||||
return result_t(f, state);
|
||||
}
|
||||
|
||||
template <class Function, class Input>
|
||||
inline function_input_iterator<Function*, Input>
|
||||
make_function_input_iterator(Function * f, Input state) {
|
||||
typedef function_input_iterator<Function*, Input> result_t;
|
||||
return result_t(f, state);
|
||||
}
|
||||
|
||||
struct infinite
|
||||
{
|
||||
infinite & operator++() { return *this; }
|
||||
infinite & operator++(int) { return *this; }
|
||||
bool operator==(infinite &) const { return false; };
|
||||
bool operator==(infinite const &) const { return false; };
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::function_input_iterator;
|
||||
using iterators::make_function_input_iterator;
|
||||
using iterators::infinite;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
95
boost/iterator/function_output_iterator.hpp
Normal file
95
boost/iterator/function_output_iterator.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
// (C) Copyright Jeremy Siek 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// Revision History:
|
||||
|
||||
// 27 Feb 2001 Jeremy Siek
|
||||
// Initial checkin.
|
||||
|
||||
#ifndef BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||
#define BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator {
|
||||
private:
|
||||
typedef function_output_iterator self;
|
||||
|
||||
class output_proxy {
|
||||
public:
|
||||
explicit output_proxy(UnaryFunction& f) BOOST_NOEXCEPT : m_f(f) { }
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class T>
|
||||
typename boost::disable_if_c<
|
||||
boost::is_same< typename boost::remove_cv< T >::type, output_proxy >::value,
|
||||
output_proxy&
|
||||
>::type operator=(const T& value) {
|
||||
m_f(value);
|
||||
return *this;
|
||||
}
|
||||
#else
|
||||
template <class T>
|
||||
typename boost::disable_if_c<
|
||||
boost::is_same< typename boost::remove_cv< typename boost::remove_reference< T >::type >::type, output_proxy >::value,
|
||||
output_proxy&
|
||||
>::type operator=(T&& value) {
|
||||
m_f(static_cast< T&& >(value));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOST_DEFAULTED_FUNCTION(output_proxy(output_proxy const& that), BOOST_NOEXCEPT : m_f(that.m_f) {})
|
||||
BOOST_DELETED_FUNCTION(output_proxy& operator=(output_proxy const&))
|
||||
|
||||
private:
|
||||
UnaryFunction& m_f;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
|
||||
explicit function_output_iterator() {}
|
||||
|
||||
explicit function_output_iterator(const UnaryFunction& f)
|
||||
: m_f(f) {}
|
||||
|
||||
output_proxy operator*() { return output_proxy(m_f); }
|
||||
self& operator++() { return *this; }
|
||||
self& operator++(int) { return *this; }
|
||||
|
||||
private:
|
||||
UnaryFunction m_f;
|
||||
};
|
||||
|
||||
template <class UnaryFunction>
|
||||
inline function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
|
||||
return function_output_iterator<UnaryFunction>(f);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::function_output_iterator;
|
||||
using iterators::make_function_output_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_FUNCTION_OUTPUT_ITERATOR_HPP
|
145
boost/iterator/indirect_iterator.hpp
Normal file
145
boost/iterator/indirect_iterator.hpp
Normal file
@ -0,0 +1,145 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
#include <boost/pointee.hpp>
|
||||
#include <boost/indirect_reference.hpp>
|
||||
|
||||
#include <boost/detail/indirect_traits.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/add_reference.hpp>
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#ifdef BOOST_MPL_CFG_NO_HAS_XXX
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <memory>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp> // must be last #include
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||
class indirect_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Iter, class Value, class Category, class Reference, class Difference>
|
||||
struct indirect_base
|
||||
{
|
||||
typedef typename std::iterator_traits<Iter>::value_type dereferenceable;
|
||||
|
||||
typedef iterator_adaptor<
|
||||
indirect_iterator<Iter, Value, Category, Reference, Difference>
|
||||
, Iter
|
||||
, typename ia_dflt_help<
|
||||
Value, pointee<dereferenceable>
|
||||
>::type
|
||||
, Category
|
||||
, typename ia_dflt_help<
|
||||
Reference
|
||||
, mpl::eval_if<
|
||||
is_same<Value,use_default>
|
||||
, indirect_reference<dereferenceable>
|
||||
, add_reference<Value>
|
||||
>
|
||||
>::type
|
||||
, Difference
|
||||
> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct indirect_base<int, int, int, int, int> {};
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <
|
||||
class Iterator
|
||||
, class Value = use_default
|
||||
, class Category = use_default
|
||||
, class Reference = use_default
|
||||
, class Difference = use_default
|
||||
>
|
||||
class indirect_iterator
|
||||
: public detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type
|
||||
{
|
||||
typedef typename detail::indirect_base<
|
||||
Iterator, Value, Category, Reference, Difference
|
||||
>::type super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
indirect_iterator() {}
|
||||
|
||||
indirect_iterator(Iterator iter)
|
||||
: super_t(iter) {}
|
||||
|
||||
template <
|
||||
class Iterator2, class Value2, class Category2
|
||||
, class Reference2, class Difference2
|
||||
>
|
||||
indirect_iterator(
|
||||
indirect_iterator<
|
||||
Iterator2, Value2, Category2, Reference2, Difference2
|
||||
> const& y
|
||||
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0
|
||||
)
|
||||
: super_t(y.base())
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
# if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x5A0 )
|
||||
return const_cast<super_t::reference>(**this->base());
|
||||
# else
|
||||
return **this->base();
|
||||
# endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
inline
|
||||
indirect_iterator<Iter> make_indirect_iterator(Iter x)
|
||||
{
|
||||
return indirect_iterator<Iter>(x);
|
||||
}
|
||||
|
||||
template <class Traits, class Iter>
|
||||
inline
|
||||
indirect_iterator<Iter,Traits> make_indirect_iterator(Iter x, Traits* = 0)
|
||||
{
|
||||
return indirect_iterator<Iter, Traits>(x);
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::indirect_iterator;
|
||||
using iterators::make_indirect_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_INDIRECT_ITERATOR_23022003THW_HPP
|
164
boost/iterator/is_lvalue_iterator.hpp
Normal file
164
boost/iterator/is_lvalue_iterator.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_LVALUE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// should be the last #includes
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace iterators {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
#ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
// Calling lvalue_preserver( <expression>, 0 ) returns a reference
|
||||
// to the expression's result if <expression> is an lvalue, or
|
||||
// not_an_lvalue() otherwise.
|
||||
struct not_an_lvalue {};
|
||||
|
||||
template <class T>
|
||||
T& lvalue_preserver(T&, int);
|
||||
|
||||
template <class U>
|
||||
not_an_lvalue lvalue_preserver(U const&, ...);
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) detail::lvalue_preserver(expr,0)
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_LVALUE_PRESERVER(expr) expr
|
||||
|
||||
#endif
|
||||
|
||||
// Guts of is_lvalue_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_lvalue_iterator_impl
|
||||
{
|
||||
// Eat implicit conversions so we don't report true for things
|
||||
// convertible to Value const&
|
||||
struct conversion_eater
|
||||
{
|
||||
conversion_eater(typename add_lvalue_reference<Value>::type);
|
||||
};
|
||||
|
||||
static char tester(conversion_eater, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_lvalue_iterator_impl<Value>::tester(
|
||||
BOOST_LVALUE_PRESERVER(*x), 0
|
||||
)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_LVALUE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_lvalue_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
|
||||
template <class It>
|
||||
struct is_non_const_lvalue_iterator_impl
|
||||
: is_lvalue_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
template< typename T > struct is_lvalue_iterator
|
||||
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_lvalue_iterator_impl<T>::value>
|
||||
{
|
||||
public:
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_lvalue_iterator,(T))
|
||||
};
|
||||
|
||||
template< typename T > struct is_non_const_lvalue_iterator
|
||||
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_non_const_lvalue_iterator_impl<T>::value>
|
||||
{
|
||||
public:
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_non_const_lvalue_iterator,(T))
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_lvalue_iterator;
|
||||
using iterators::is_non_const_lvalue_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // IS_LVALUE_ITERATOR_DWA2003112_HPP
|
119
boost/iterator/is_readable_iterator.hpp
Normal file
119
boost/iterator/is_readable_iterator.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
# define IS_READABLE_ITERATOR_DWA2003112_HPP
|
||||
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
#include <boost/type_traits/add_lvalue_reference.hpp>
|
||||
|
||||
#include <boost/iterator/detail/any_conversion_eater.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
// should be the last #include
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
#ifndef BOOST_NO_IS_CONVERTIBLE
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace iterators {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Guts of is_readable_iterator. Value is the iterator's value_type
|
||||
// and the result is computed in the nested rebind template.
|
||||
template <class Value>
|
||||
struct is_readable_iterator_impl
|
||||
{
|
||||
static char tester(typename add_lvalue_reference<Value>::type, int);
|
||||
static char (& tester(any_conversion_eater, ...) )[2];
|
||||
|
||||
template <class It>
|
||||
struct rebind
|
||||
{
|
||||
static It& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = (
|
||||
sizeof(
|
||||
is_readable_iterator_impl<Value>::tester(*x, 1)
|
||||
) == 1
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
#undef BOOST_READABLE_PRESERVER
|
||||
|
||||
//
|
||||
// void specializations to handle std input and output iterators
|
||||
//
|
||||
template <>
|
||||
struct is_readable_iterator_impl<void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_readable_iterator_impl<const volatile void>
|
||||
{
|
||||
template <class It>
|
||||
struct rebind : boost::mpl::false_
|
||||
{};
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// This level of dispatching is required for Borland. We might save
|
||||
// an instantiation by removing it for others.
|
||||
//
|
||||
template <class It>
|
||||
struct is_readable_iterator_impl2
|
||||
: is_readable_iterator_impl<
|
||||
BOOST_DEDUCED_TYPENAME std::iterator_traits<It>::value_type const
|
||||
>::template rebind<It>
|
||||
{};
|
||||
} // namespace detail
|
||||
|
||||
template< typename T > struct is_readable_iterator
|
||||
: public ::boost::integral_constant<bool,::boost::iterators::detail::is_readable_iterator_impl2<T>::value>
|
||||
{
|
||||
public:
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_readable_iterator,(T))
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::is_readable_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // IS_READABLE_ITERATOR_DWA2003112_HPP
|
509
boost/iterator/iterator_archetypes.hpp
Normal file
509
boost/iterator/iterator_archetypes.hpp
Normal file
@ -0,0 +1,509 @@
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
#define BOOST_ITERATOR_ARCHETYPES_HPP
|
||||
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/iterator/detail/facade_iterator_category.hpp>
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <boost/concept_archetype.hpp>
|
||||
|
||||
#include <boost/mpl/bitand.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/mpl/equal_to.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct access_archetype;
|
||||
|
||||
template <class Derived, class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype;
|
||||
|
||||
namespace archetypes
|
||||
{
|
||||
enum {
|
||||
readable_iterator_bit = 1
|
||||
, writable_iterator_bit = 2
|
||||
, swappable_iterator_bit = 4
|
||||
, lvalue_iterator_bit = 8
|
||||
};
|
||||
|
||||
// Not quite tags, since dispatching wouldn't work.
|
||||
typedef mpl::int_<readable_iterator_bit>::type readable_iterator_t;
|
||||
typedef mpl::int_<writable_iterator_bit>::type writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|writable_iterator_bit)
|
||||
>::type readable_writable_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(readable_iterator_bit|lvalue_iterator_bit)
|
||||
>::type readable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<
|
||||
(lvalue_iterator_bit|writable_iterator_bit)
|
||||
>::type writable_lvalue_iterator_t;
|
||||
|
||||
typedef mpl::int_<swappable_iterator_bit>::type swappable_iterator_t;
|
||||
typedef mpl::int_<lvalue_iterator_bit>::type lvalue_iterator_t;
|
||||
|
||||
template <class Derived, class Base>
|
||||
struct has_access
|
||||
: mpl::equal_to<
|
||||
mpl::bitand_<Derived,Base>
|
||||
, Base
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
struct assign_proxy
|
||||
{
|
||||
assign_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_proxy
|
||||
{
|
||||
operator T() { return static_object<T>::get(); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct read_write_proxy
|
||||
: read_proxy<T> // Use to inherit from assign_proxy, but that doesn't work. -JGS
|
||||
{
|
||||
read_write_proxy& operator=(T) { return *this; }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arrow_proxy
|
||||
{
|
||||
T const* operator->() const { return 0; }
|
||||
};
|
||||
|
||||
struct no_operator_brackets {};
|
||||
|
||||
template <class ValueType>
|
||||
struct readable_operator_brackets
|
||||
{
|
||||
read_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class ValueType>
|
||||
struct writable_operator_brackets
|
||||
{
|
||||
read_write_proxy<ValueType> operator[](std::ptrdiff_t n) const { return read_write_proxy<ValueType>(); }
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct operator_brackets
|
||||
: mpl::eval_if<
|
||||
is_convertible<TraversalCategory, random_access_traversal_tag>
|
||||
, mpl::eval_if<
|
||||
archetypes::has_access<
|
||||
AccessCategory
|
||||
, archetypes::writable_iterator_t
|
||||
>
|
||||
, mpl::identity<writable_operator_brackets<Value> >
|
||||
, mpl::if_<
|
||||
archetypes::has_access<
|
||||
AccessCategory
|
||||
, archetypes::readable_iterator_t
|
||||
>
|
||||
, readable_operator_brackets<Value>
|
||||
, no_operator_brackets
|
||||
>
|
||||
>
|
||||
, mpl::identity<no_operator_brackets>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class TraversalCategory>
|
||||
struct traversal_archetype_impl
|
||||
{
|
||||
template <class Derived,class Value> struct archetype;
|
||||
};
|
||||
|
||||
// Constructor argument for those iterators that
|
||||
// are not default constructible
|
||||
struct ctor_arg {};
|
||||
|
||||
template <class Derived, class Value, class TraversalCategory>
|
||||
struct traversal_archetype_
|
||||
: traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
{
|
||||
typedef typename
|
||||
traversal_archetype_impl<TraversalCategory>::template archetype<Derived,Value>
|
||||
base;
|
||||
|
||||
traversal_archetype_() {}
|
||||
|
||||
traversal_archetype_(ctor_arg arg)
|
||||
: base(arg)
|
||||
{}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<incrementable_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
{
|
||||
explicit archetype(ctor_arg) {}
|
||||
|
||||
struct bogus { }; // This use to be void, but that causes trouble for iterator_facade. Need more research. -JGS
|
||||
typedef bogus difference_type;
|
||||
|
||||
Derived& operator++() { return (Derived&)static_object<Derived>::get(); }
|
||||
Derived operator++(int) const { return (Derived&)static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<single_pass_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public equality_comparable< traversal_archetype_<Derived, Value, single_pass_traversal_tag> >,
|
||||
public traversal_archetype_<Derived, Value, incrementable_traversal_tag>
|
||||
{
|
||||
explicit archetype(ctor_arg arg)
|
||||
: traversal_archetype_<Derived, Value, incrementable_traversal_tag>(arg)
|
||||
{}
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator==(traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, single_pass_traversal_tag> const&) { return true; }
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<forward_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, single_pass_traversal_tag>
|
||||
{
|
||||
archetype()
|
||||
: traversal_archetype_<Derived, Value, single_pass_traversal_tag>(ctor_arg())
|
||||
{}
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<bidirectional_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, forward_traversal_tag>
|
||||
{
|
||||
Derived& operator--() { return static_object<Derived>::get(); }
|
||||
Derived operator--(int) const { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct traversal_archetype_impl<random_access_traversal_tag>
|
||||
{
|
||||
template<class Derived, class Value>
|
||||
struct archetype
|
||||
: public traversal_archetype_<Derived, Value, bidirectional_traversal_tag>
|
||||
{
|
||||
Derived& operator+=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
Derived& operator-=(std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t) { return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator+(std::ptrdiff_t,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
Derived& operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
std::ptrdiff_t)
|
||||
{ return static_object<Derived>::get(); }
|
||||
|
||||
template <class Derived, class Value>
|
||||
std::ptrdiff_t operator-(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return 0; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator>(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator<=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
template <class Derived, class Value>
|
||||
bool operator>=(traversal_archetype_<Derived, Value, random_access_traversal_tag> const&,
|
||||
traversal_archetype_<Derived, Value, random_access_traversal_tag> const&)
|
||||
{ return true; }
|
||||
|
||||
struct bogus_type;
|
||||
|
||||
template <class Value>
|
||||
struct convertible_type
|
||||
: mpl::if_< is_const<Value>,
|
||||
typename remove_const<Value>::type,
|
||||
bogus_type >
|
||||
{};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <class> struct undefined;
|
||||
|
||||
template <class AccessCategory>
|
||||
struct iterator_access_archetype_impl
|
||||
{
|
||||
template <class Value> struct archetype;
|
||||
};
|
||||
|
||||
template <class Value, class AccessCategory>
|
||||
struct iterator_access_archetype
|
||||
: iterator_access_archetype_impl<
|
||||
AccessCategory
|
||||
>::template archetype<Value>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
typedef typename remove_cv<Value>::type value_type;
|
||||
typedef Value reference;
|
||||
typedef Value* pointer;
|
||||
|
||||
value_type operator*() const { return static_object<value_type>::get(); }
|
||||
|
||||
detail::arrow_proxy<Value> operator->() const { return detail::arrow_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
archetypes::writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
{
|
||||
BOOST_STATIC_ASSERT(!is_const<Value>::value);
|
||||
typedef void value_type;
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
detail::assign_proxy<Value> operator*() const { return detail::assign_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<
|
||||
archetypes::readable_writable_iterator_t
|
||||
>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef detail::read_write_proxy<Value> reference;
|
||||
|
||||
detail::read_write_proxy<Value> operator*() const { return detail::read_write_proxy<Value>(); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::readable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, archetypes::readable_iterator_t
|
||||
>
|
||||
{
|
||||
typedef Value& reference;
|
||||
|
||||
Value& operator*() const { return static_object<Value>::get(); }
|
||||
Value* operator->() const { return 0; }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterator_access_archetype_impl<archetypes::writable_lvalue_iterator_t>
|
||||
{
|
||||
template <class Value>
|
||||
struct archetype
|
||||
: public virtual iterator_access_archetype<
|
||||
Value, archetypes::readable_lvalue_iterator_t
|
||||
>
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!is_const<Value>::value));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype;
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct traversal_archetype_base
|
||||
: detail::operator_brackets<
|
||||
typename remove_cv<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>
|
||||
, detail::traversal_archetype_<
|
||||
iterator_archetype<Value, AccessCategory, TraversalCategory>
|
||||
, Value
|
||||
, TraversalCategory
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype_base
|
||||
: iterator_access_archetype<Value, AccessCategory>
|
||||
, traversal_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
{
|
||||
typedef iterator_access_archetype<Value, AccessCategory> access;
|
||||
|
||||
typedef typename detail::facade_iterator_category<
|
||||
TraversalCategory
|
||||
, typename mpl::eval_if<
|
||||
archetypes::has_access<
|
||||
AccessCategory, archetypes::writable_iterator_t
|
||||
>
|
||||
, remove_const<Value>
|
||||
, add_const<Value>
|
||||
>::type
|
||||
, typename access::reference
|
||||
>::type iterator_category;
|
||||
|
||||
// Needed for some broken libraries (see below)
|
||||
struct workaround_iterator_base
|
||||
{
|
||||
typedef typename iterator_archetype_base::iterator_category iterator_category;
|
||||
typedef Value value_type;
|
||||
typedef typename traversal_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::difference_type difference_type;
|
||||
typedef typename access::pointer pointer;
|
||||
typedef typename access::reference reference;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <class Value, class AccessCategory, class TraversalCategory>
|
||||
struct iterator_archetype
|
||||
: public detail::iterator_archetype_base<Value, AccessCategory, TraversalCategory>
|
||||
|
||||
// These broken libraries require derivation from std::iterator
|
||||
// (or related magic) in order to handle iter_swap and other
|
||||
// iterator operations
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
, public detail::iterator_archetype_base<
|
||||
Value, AccessCategory, TraversalCategory
|
||||
>::workaround_iterator_base
|
||||
# endif
|
||||
{
|
||||
// Derivation from std::iterator above caused references to nested
|
||||
// types to be ambiguous, so now we have to redeclare them all
|
||||
// here.
|
||||
# if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, < 310) \
|
||||
|| BOOST_WORKAROUND(_RWSTD_VER, BOOST_TESTED_AT(0x20101))
|
||||
|
||||
typedef detail::iterator_archetype_base<
|
||||
Value,AccessCategory,TraversalCategory
|
||||
> base;
|
||||
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator_category iterator_category;
|
||||
# endif
|
||||
|
||||
iterator_archetype() { }
|
||||
iterator_archetype(iterator_archetype const& x)
|
||||
: detail::iterator_archetype_base<
|
||||
Value
|
||||
, AccessCategory
|
||||
, TraversalCategory
|
||||
>(x)
|
||||
{}
|
||||
|
||||
iterator_archetype& operator=(iterator_archetype const&)
|
||||
{ return *this; }
|
||||
|
||||
# if 0
|
||||
// Optional conversion from mutable
|
||||
iterator_archetype(
|
||||
iterator_archetype<
|
||||
typename detail::convertible_type<Value>::type
|
||||
, AccessCategory
|
||||
, TraversalCategory> const&
|
||||
);
|
||||
# endif
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
// Backward compatibility names
|
||||
namespace iterator_archetypes = iterators::archetypes;
|
||||
using iterators::access_archetype;
|
||||
using iterators::traversal_archetype;
|
||||
using iterators::iterator_archetype;
|
||||
using iterators::undefined;
|
||||
using iterators::iterator_access_archetype_impl;
|
||||
using iterators::traversal_archetype_base;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_ARCHETYPES_HPP
|
95
boost/iterator/minimum_category.hpp
Normal file
95
boost/iterator/minimum_category.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright David Abrahams 2003. Use, modification and distribution is
|
||||
// subject to the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
# define BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
||||
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
|
||||
# include <boost/mpl/placeholders.hpp>
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
namespace detail {
|
||||
|
||||
template <bool GreaterEqual, bool LessEqual>
|
||||
struct minimum_category_impl;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct error_not_related_by_convertibility;
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<true,true>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_same<T1,T2>::value));
|
||||
typedef T1 type;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category_impl<false,false>
|
||||
{
|
||||
template <class T1, class T2> struct apply
|
||||
: error_not_related_by_convertibility<T1,T2>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Returns the minimum category type or fails to compile
|
||||
// if T1 and T2 are unrelated.
|
||||
//
|
||||
template <class T1 = mpl::_1, class T2 = mpl::_2>
|
||||
struct minimum_category
|
||||
{
|
||||
typedef boost::iterators::detail::minimum_category_impl<
|
||||
::boost::is_convertible<T1,T2>::value
|
||||
, ::boost::is_convertible<T2,T1>::value
|
||||
> outer;
|
||||
|
||||
typedef typename outer::template apply<T1,T2> inner;
|
||||
typedef typename inner::type type;
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,minimum_category,(T1,T2))
|
||||
};
|
||||
|
||||
template <>
|
||||
struct minimum_category<mpl::_1,mpl::_2>
|
||||
{
|
||||
template <class T1, class T2>
|
||||
struct apply : minimum_category<T1,T2>
|
||||
{};
|
||||
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(2,minimum_category,(mpl::_1,mpl::_2))
|
||||
};
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ITERATOR_MINIMUM_CATEGORY_HPP_INCLUDED_
|
265
boost/iterator/new_iterator_tests.hpp
Normal file
265
boost/iterator/new_iterator_tests.hpp
Normal file
@ -0,0 +1,265 @@
|
||||
#ifndef BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
# define BOOST_NEW_ITERATOR_TESTS_HPP
|
||||
|
||||
//
|
||||
// Copyright (c) David Abrahams 2001.
|
||||
// Copyright (c) Jeremy Siek 2001-2003.
|
||||
// Copyright (c) Thomas Witt 2002.
|
||||
//
|
||||
// Use, modification and distribution is subject to the
|
||||
// Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
// This is meant to be the beginnings of a comprehensive, generic
|
||||
// test suite for STL concepts such as iterators and containers.
|
||||
//
|
||||
// Revision History:
|
||||
// 28 Oct 2002 Started update for new iterator categories
|
||||
// (Jeremy Siek)
|
||||
// 28 Apr 2002 Fixed input iterator requirements.
|
||||
// For a == b a++ == b++ is no longer required.
|
||||
// See 24.1.1/3 for details.
|
||||
// (Thomas Witt)
|
||||
// 08 Feb 2001 Fixed bidirectional iterator test so that
|
||||
// --i is no longer a precondition.
|
||||
// (Jeremy Siek)
|
||||
// 04 Feb 2001 Added lvalue test, corrected preconditions
|
||||
// (David Abrahams)
|
||||
|
||||
# include <iterator>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/concept_archetype.hpp> // for detail::dummy_constructor
|
||||
# include <boost/pending/iterator_tests.hpp>
|
||||
# include <boost/iterator/is_readable_iterator.hpp>
|
||||
# include <boost/iterator/is_lvalue_iterator.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/mpl/and.hpp>
|
||||
|
||||
# include <boost/iterator/detail/config_def.hpp>
|
||||
# include <boost/detail/is_incrementable.hpp>
|
||||
# include <boost/core/lightweight_test.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
|
||||
// Do separate tests for *i++ so we can treat, e.g., smart pointers,
|
||||
// as readable and/or writable iterators.
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
|
||||
{
|
||||
T v2(*i1++);
|
||||
BOOST_TEST(v == v2);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
|
||||
{}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(Iterator i1, T v, mpl::true_)
|
||||
{
|
||||
++i1; // we just wrote into that position
|
||||
*i1++ = v;
|
||||
Iterator x(i1++);
|
||||
(void)x;
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_traversal_test(const Iterator i1, T v, mpl::false_)
|
||||
{}
|
||||
|
||||
|
||||
// Preconditions: *i == v
|
||||
template <class Iterator, class T>
|
||||
void readable_iterator_test(const Iterator i1, T v)
|
||||
{
|
||||
Iterator i2(i1); // Copy Constructible
|
||||
typedef typename std::iterator_traits<Iterator>::reference ref_t;
|
||||
ref_t r1 = *i1;
|
||||
ref_t r2 = *i2;
|
||||
T v1 = r1;
|
||||
T v2 = r2;
|
||||
BOOST_TEST(v1 == v);
|
||||
BOOST_TEST(v2 == v);
|
||||
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
readable_iterator_traversal_test(i1, v, detail::is_postfix_incrementable<Iterator>());
|
||||
|
||||
// I think we don't really need this as it checks the same things as
|
||||
// the above code.
|
||||
BOOST_STATIC_ASSERT(is_readable_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void writable_iterator_test(Iterator i, T v, T v2)
|
||||
{
|
||||
Iterator i2(i); // Copy Constructible
|
||||
*i2 = v;
|
||||
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
|
||||
writable_iterator_traversal_test(
|
||||
i, v2, mpl::and_<
|
||||
detail::is_incrementable<Iterator>
|
||||
, detail::is_postfix_incrementable<Iterator>
|
||||
>());
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
void swappable_iterator_test(Iterator i, Iterator j)
|
||||
{
|
||||
Iterator i2(i), j2(j);
|
||||
typename std::iterator_traits<Iterator>::value_type bi = *i, bj = *j;
|
||||
iter_swap(i2, j2);
|
||||
typename std::iterator_traits<Iterator>::value_type ai = *i, aj = *j;
|
||||
BOOST_TEST(bi == aj && bj == ai);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void constant_lvalue_iterator_test(Iterator i, T v1)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
BOOST_STATIC_ASSERT((is_same<const value_type&, reference>::value));
|
||||
const T& v2 = *i2;
|
||||
BOOST_TEST(v1 == v2);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(!is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void non_const_lvalue_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator i2(i);
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
typedef typename std::iterator_traits<Iterator>::reference reference;
|
||||
BOOST_STATIC_ASSERT((is_same<value_type&, reference>::value));
|
||||
T& v3 = *i2;
|
||||
BOOST_TEST(v1 == v3);
|
||||
|
||||
// A non-const lvalue iterator is not neccessarily writable, but we
|
||||
// are assuming the value_type is assignable here
|
||||
*i = v2;
|
||||
|
||||
T& v4 = *i2;
|
||||
BOOST_TEST(v2 == v4);
|
||||
# ifndef BOOST_NO_LVALUE_RETURN_DETECTION
|
||||
BOOST_STATIC_ASSERT(is_lvalue_iterator<Iterator>::value);
|
||||
BOOST_STATIC_ASSERT(is_non_const_lvalue_iterator<Iterator>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_readable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
Iterator i2;
|
||||
Iterator i3(i);
|
||||
i2 = i;
|
||||
BOOST_TEST(i2 == i3);
|
||||
BOOST_TEST(i != j);
|
||||
BOOST_TEST(i2 != j);
|
||||
readable_iterator_test(i, val1);
|
||||
readable_iterator_test(i2, val1);
|
||||
readable_iterator_test(i3, val1);
|
||||
|
||||
BOOST_TEST(i == i2++);
|
||||
BOOST_TEST(i != ++i3);
|
||||
|
||||
readable_iterator_test(i2, val2);
|
||||
readable_iterator_test(i3, val2);
|
||||
|
||||
readable_iterator_test(i, val1);
|
||||
}
|
||||
|
||||
template <class Iterator, class T>
|
||||
void forward_swappable_iterator_test(Iterator i, Iterator j, T val1, T val2)
|
||||
{
|
||||
forward_readable_iterator_test(i, j, val1, val2);
|
||||
Iterator i2 = i;
|
||||
++i2;
|
||||
swappable_iterator_test(i, i2);
|
||||
}
|
||||
|
||||
// bidirectional
|
||||
// Preconditions: *i == v1, *++i == v2
|
||||
template <class Iterator, class T>
|
||||
void bidirectional_readable_iterator_test(Iterator i, T v1, T v2)
|
||||
{
|
||||
Iterator j(i);
|
||||
++j;
|
||||
forward_readable_iterator_test(i, j, v1, v2);
|
||||
++i;
|
||||
|
||||
Iterator i1 = i, i2 = i;
|
||||
|
||||
BOOST_TEST(i == i1--);
|
||||
BOOST_TEST(i != --i2);
|
||||
|
||||
readable_iterator_test(i, v2);
|
||||
readable_iterator_test(i1, v1);
|
||||
readable_iterator_test(i2, v1);
|
||||
|
||||
--i;
|
||||
BOOST_TEST(i == i1);
|
||||
BOOST_TEST(i == i2);
|
||||
++i1;
|
||||
++i2;
|
||||
|
||||
readable_iterator_test(i, v1);
|
||||
readable_iterator_test(i1, v2);
|
||||
readable_iterator_test(i2, v2);
|
||||
}
|
||||
|
||||
// random access
|
||||
// Preconditions: [i,i+N) is a valid range
|
||||
template <class Iterator, class TrueVals>
|
||||
void random_access_readable_iterator_test(Iterator i, int N, TrueVals vals)
|
||||
{
|
||||
bidirectional_readable_iterator_test(i, vals[0], vals[1]);
|
||||
const Iterator j = i;
|
||||
int c;
|
||||
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
BOOST_TEST(i == j + c);
|
||||
BOOST_TEST(*i == vals[c]);
|
||||
typename std::iterator_traits<Iterator>::value_type x = j[c];
|
||||
BOOST_TEST(*i == x);
|
||||
BOOST_TEST(*i == *(j + c));
|
||||
BOOST_TEST(*i == *(c + j));
|
||||
++i;
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
}
|
||||
|
||||
Iterator k = j + N - 1;
|
||||
for (c = 0; c < N-1; ++c)
|
||||
{
|
||||
BOOST_TEST(i == k - c);
|
||||
BOOST_TEST(*i == vals[N - 1 - c]);
|
||||
typename std::iterator_traits<Iterator>::value_type x = j[N - 1 - c];
|
||||
BOOST_TEST(*i == x);
|
||||
Iterator q = k - c;
|
||||
BOOST_TEST(*i == *q);
|
||||
BOOST_TEST(i > j);
|
||||
BOOST_TEST(i >= j);
|
||||
BOOST_TEST(j <= i);
|
||||
BOOST_TEST(j < i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
# include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_NEW_ITERATOR_TESTS_HPP
|
76
boost/iterator/permutation_iterator.hpp
Normal file
76
boost/iterator/permutation_iterator.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
// (C) Copyright Toon Knapen 2001.
|
||||
// (C) Copyright David Abrahams 2003.
|
||||
// (C) Copyright Roland Richter 2003.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PERMUTATION_ITERATOR_HPP
|
||||
#define BOOST_PERMUTATION_ITERATOR_HPP
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template< class ElementIterator
|
||||
, class IndexIterator>
|
||||
class permutation_iterator
|
||||
: public iterator_adaptor<
|
||||
permutation_iterator<ElementIterator, IndexIterator>
|
||||
, IndexIterator, typename std::iterator_traits<ElementIterator>::value_type
|
||||
, use_default, typename std::iterator_traits<ElementIterator>::reference>
|
||||
{
|
||||
typedef iterator_adaptor<
|
||||
permutation_iterator<ElementIterator, IndexIterator>
|
||||
, IndexIterator, typename std::iterator_traits<ElementIterator>::value_type
|
||||
, use_default, typename std::iterator_traits<ElementIterator>::reference> super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
permutation_iterator() : m_elt_iter() {}
|
||||
|
||||
explicit permutation_iterator(ElementIterator x, IndexIterator y)
|
||||
: super_t(y), m_elt_iter(x) {}
|
||||
|
||||
template<class OtherElementIterator, class OtherIndexIterator>
|
||||
permutation_iterator(
|
||||
permutation_iterator<OtherElementIterator, OtherIndexIterator> const& r
|
||||
, typename enable_if_convertible<OtherElementIterator, ElementIterator>::type* = 0
|
||||
, typename enable_if_convertible<OtherIndexIterator, IndexIterator>::type* = 0
|
||||
)
|
||||
: super_t(r.base()), m_elt_iter(r.m_elt_iter)
|
||||
{}
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{ return *(m_elt_iter + *this->base()); }
|
||||
|
||||
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
|
||||
template <class,class> friend class permutation_iterator;
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
ElementIterator m_elt_iter;
|
||||
};
|
||||
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
inline permutation_iterator<ElementIterator, IndexIterator>
|
||||
make_permutation_iterator( ElementIterator e, IndexIterator i )
|
||||
{
|
||||
return permutation_iterator<ElementIterator, IndexIterator>( e, i );
|
||||
}
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::permutation_iterator;
|
||||
using iterators::make_permutation_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
179
boost/iterator/transform_iterator.hpp
Normal file
179
boost/iterator/transform_iterator.hpp
Normal file
@ -0,0 +1,179 @@
|
||||
// (C) Copyright David Abrahams 2002.
|
||||
// (C) Copyright Jeremy Siek 2002.
|
||||
// (C) Copyright Thomas Witt 2002.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
#ifndef BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
#define BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/iterator/detail/enable_if.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
#include <boost/type_traits/function_traits.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_class.hpp>
|
||||
#include <boost/type_traits/is_function.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
#include <boost/static_assert.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
template <class UnaryFunction, class Iterator, class Reference = use_default, class Value = use_default>
|
||||
class transform_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
// Compute the iterator_adaptor instantiation to be used for transform_iterator
|
||||
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
||||
struct transform_iterator_base
|
||||
{
|
||||
private:
|
||||
// By default, dereferencing the iterator yields the same as
|
||||
// the function.
|
||||
typedef typename ia_dflt_help<
|
||||
Reference
|
||||
#ifdef BOOST_RESULT_OF_USE_TR1
|
||||
, result_of<const UnaryFunc(typename std::iterator_traits<Iterator>::reference)>
|
||||
#else
|
||||
, result_of<const UnaryFunc&(typename std::iterator_traits<Iterator>::reference)>
|
||||
#endif
|
||||
>::type reference;
|
||||
|
||||
// To get the default for Value: remove any reference on the
|
||||
// result type, but retain any constness to signal
|
||||
// non-writability. Note that if we adopt Thomas' suggestion
|
||||
// to key non-writability *only* on the Reference argument,
|
||||
// we'd need to strip constness here as well.
|
||||
typedef typename ia_dflt_help<
|
||||
Value
|
||||
, remove_reference<reference>
|
||||
>::type cv_value_type;
|
||||
|
||||
public:
|
||||
typedef iterator_adaptor<
|
||||
transform_iterator<UnaryFunc, Iterator, Reference, Value>
|
||||
, Iterator
|
||||
, cv_value_type
|
||||
, use_default // Leave the traversal category alone
|
||||
, reference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class UnaryFunc, class Iterator, class Reference, class Value>
|
||||
class transform_iterator
|
||||
: public boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
||||
{
|
||||
typedef typename
|
||||
boost::iterators::detail::transform_iterator_base<UnaryFunc, Iterator, Reference, Value>::type
|
||||
super_t;
|
||||
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
transform_iterator() { }
|
||||
|
||||
transform_iterator(Iterator const& x, UnaryFunc f)
|
||||
: super_t(x), m_f(f) { }
|
||||
|
||||
explicit transform_iterator(Iterator const& x)
|
||||
: super_t(x)
|
||||
{
|
||||
// Pro8 is a little too aggressive about instantiating the
|
||||
// body of this function.
|
||||
#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
// don't provide this constructor if UnaryFunc is a
|
||||
// function pointer type, since it will be 0. Too dangerous.
|
||||
BOOST_STATIC_ASSERT(is_class<UnaryFunc>::value);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <
|
||||
class OtherUnaryFunction
|
||||
, class OtherIterator
|
||||
, class OtherReference
|
||||
, class OtherValue>
|
||||
transform_iterator(
|
||||
transform_iterator<OtherUnaryFunction, OtherIterator, OtherReference, OtherValue> const& t
|
||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
||||
, typename enable_if_convertible<OtherUnaryFunction, UnaryFunc>::type* = 0
|
||||
#endif
|
||||
)
|
||||
: super_t(t.base()), m_f(t.functor())
|
||||
{}
|
||||
|
||||
UnaryFunc functor() const
|
||||
{ return m_f; }
|
||||
|
||||
private:
|
||||
typename super_t::reference dereference() const
|
||||
{ return m_f(*this->base()); }
|
||||
|
||||
// Probably should be the initial base class so it can be
|
||||
// optimized away via EBO if it is an empty class.
|
||||
UnaryFunc m_f;
|
||||
};
|
||||
|
||||
template <class UnaryFunc, class Iterator>
|
||||
inline transform_iterator<UnaryFunc, Iterator>
|
||||
make_transform_iterator(Iterator it, UnaryFunc fun)
|
||||
{
|
||||
return transform_iterator<UnaryFunc, Iterator>(it, fun);
|
||||
}
|
||||
|
||||
// Version which allows explicit specification of the UnaryFunc
|
||||
// type.
|
||||
//
|
||||
// This generator is not provided if UnaryFunc is a function
|
||||
// pointer type, because it's too dangerous: the default-constructed
|
||||
// function pointer in the iterator be 0, leading to a runtime
|
||||
// crash.
|
||||
template <class UnaryFunc, class Iterator>
|
||||
inline typename iterators::enable_if<
|
||||
is_class<UnaryFunc> // We should probably find a cheaper test than is_class<>
|
||||
, transform_iterator<UnaryFunc, Iterator>
|
||||
>::type
|
||||
make_transform_iterator(Iterator it)
|
||||
{
|
||||
return transform_iterator<UnaryFunc, Iterator>(it, UnaryFunc());
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
template <class Return, class Argument, class Iterator>
|
||||
inline transform_iterator< Return (*)(Argument), Iterator, Return>
|
||||
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
||||
{
|
||||
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::transform_iterator;
|
||||
using iterators::make_transform_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/iterator/detail/config_undef.hpp>
|
||||
|
||||
#endif // BOOST_TRANSFORM_ITERATOR_23022003THW_HPP
|
367
boost/iterator/zip_iterator.hpp
Normal file
367
boost/iterator/zip_iterator.hpp
Normal file
@ -0,0 +1,367 @@
|
||||
// Copyright David Abrahams and Thomas Becker 2000-2006.
|
||||
// Copyright Kohei Takahashi 2012-2014.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
# define BOOST_ZIP_ITERATOR_TMB_07_13_2003_HPP_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/iterator/iterator_adaptor.hpp> // for enable_if_convertible
|
||||
#include <boost/iterator/iterator_categories.hpp>
|
||||
|
||||
#include <boost/iterator/minimum_category.hpp>
|
||||
|
||||
#include <utility> // for std::pair
|
||||
#include <boost/fusion/adapted/boost_tuple.hpp> // for backward compatibility
|
||||
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/fold.hpp>
|
||||
#include <boost/mpl/transform.hpp>
|
||||
#include <boost/mpl/placeholders.hpp>
|
||||
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
#include <boost/fusion/algorithm/transformation/transform.hpp>
|
||||
#include <boost/fusion/sequence/convert.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/at_c.hpp>
|
||||
#include <boost/fusion/sequence/comparison/equal_to.hpp>
|
||||
#include <boost/fusion/support/tag_of_fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace iterators {
|
||||
|
||||
// Zip iterator forward declaration for zip_iterator_base
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// Functors to be used with tuple algorithms
|
||||
//
|
||||
template<typename DiffType>
|
||||
class advance_iterator
|
||||
{
|
||||
public:
|
||||
advance_iterator(DiffType step) : m_step(step) {}
|
||||
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ it += m_step; }
|
||||
|
||||
private:
|
||||
DiffType m_step;
|
||||
};
|
||||
//
|
||||
struct increment_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ ++it; }
|
||||
};
|
||||
//
|
||||
struct decrement_iterator
|
||||
{
|
||||
template<typename Iterator>
|
||||
void operator()(Iterator& it) const
|
||||
{ --it; }
|
||||
};
|
||||
//
|
||||
struct dereference_iterator
|
||||
{
|
||||
template<typename>
|
||||
struct result;
|
||||
|
||||
template<typename This, typename Iterator>
|
||||
struct result<This(Iterator)>
|
||||
{
|
||||
typedef typename
|
||||
remove_cv<typename remove_reference<Iterator>::type>::type
|
||||
iterator;
|
||||
|
||||
typedef typename iterator_reference<iterator>::type type;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
typename result<dereference_iterator(Iterator)>::type
|
||||
operator()(Iterator const& it) const
|
||||
{ return *it; }
|
||||
};
|
||||
|
||||
// Metafunction to obtain the type of the tuple whose element types
|
||||
// are the reference types of an iterator tuple.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct tuple_of_references
|
||||
: mpl::transform<
|
||||
IteratorTuple,
|
||||
iterator_reference<mpl::_1>
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
// Specialization for std::pair
|
||||
template<typename Iterator1, typename Iterator2>
|
||||
struct tuple_of_references<std::pair<Iterator1, Iterator2> >
|
||||
{
|
||||
typedef std::pair<
|
||||
typename iterator_reference<Iterator1>::type
|
||||
, typename iterator_reference<Iterator2>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
// Metafunction to obtain the minimal traversal tag in a tuple
|
||||
// of iterators.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct minimum_traversal_category_in_iterator_tuple
|
||||
{
|
||||
typedef typename mpl::transform<
|
||||
IteratorTuple
|
||||
, pure_traversal_tag<iterator_traversal<> >
|
||||
>::type tuple_of_traversal_tags;
|
||||
|
||||
typedef typename mpl::fold<
|
||||
tuple_of_traversal_tags
|
||||
, random_access_traversal_tag
|
||||
, minimum_category<>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename Iterator1, typename Iterator2>
|
||||
struct minimum_traversal_category_in_iterator_tuple<std::pair<Iterator1, Iterator2> >
|
||||
{
|
||||
typedef typename pure_traversal_tag<
|
||||
typename iterator_traversal<Iterator1>::type
|
||||
>::type iterator1_traversal;
|
||||
typedef typename pure_traversal_tag<
|
||||
typename iterator_traversal<Iterator2>::type
|
||||
>::type iterator2_traversal;
|
||||
|
||||
typedef typename minimum_category<
|
||||
iterator1_traversal
|
||||
, typename minimum_category<
|
||||
iterator2_traversal
|
||||
, random_access_traversal_tag
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class zip_iterator_base
|
||||
//
|
||||
// Builds and exposes the iterator facade type from which the zip
|
||||
// iterator will be derived.
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
struct zip_iterator_base
|
||||
{
|
||||
private:
|
||||
// Reference type is the type of the tuple obtained from the
|
||||
// iterators' reference types.
|
||||
typedef typename
|
||||
detail::tuple_of_references<IteratorTuple>::type reference;
|
||||
|
||||
// Value type is the same as reference type.
|
||||
typedef reference value_type;
|
||||
|
||||
// Difference type is the first iterator's difference type
|
||||
typedef typename iterator_difference<
|
||||
typename mpl::at_c<IteratorTuple, 0>::type
|
||||
>::type difference_type;
|
||||
|
||||
// Traversal catetgory is the minimum traversal category in the
|
||||
// iterator tuple.
|
||||
typedef typename
|
||||
detail::minimum_traversal_category_in_iterator_tuple<
|
||||
IteratorTuple
|
||||
>::type traversal_category;
|
||||
public:
|
||||
|
||||
// The iterator facade type from which the zip iterator will
|
||||
// be derived.
|
||||
typedef iterator_facade<
|
||||
zip_iterator<IteratorTuple>,
|
||||
value_type,
|
||||
traversal_category,
|
||||
reference,
|
||||
difference_type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct zip_iterator_base<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template <typename reference>
|
||||
struct converter
|
||||
{
|
||||
template <typename Seq>
|
||||
static reference call(Seq seq)
|
||||
{
|
||||
typedef typename fusion::traits::tag_of<reference>::type tag;
|
||||
return fusion::convert<tag>(seq);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Reference1, typename Reference2>
|
||||
struct converter<std::pair<Reference1, Reference2> >
|
||||
{
|
||||
typedef std::pair<Reference1, Reference2> reference;
|
||||
template <typename Seq>
|
||||
static reference call(Seq seq)
|
||||
{
|
||||
return reference(
|
||||
fusion::at_c<0>(seq)
|
||||
, fusion::at_c<1>(seq));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// zip_iterator class definition
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
class zip_iterator :
|
||||
public detail::zip_iterator_base<IteratorTuple>::type
|
||||
{
|
||||
|
||||
// Typedef super_t as our base class.
|
||||
typedef typename
|
||||
detail::zip_iterator_base<IteratorTuple>::type super_t;
|
||||
|
||||
// iterator_core_access is the iterator's best friend.
|
||||
friend class iterator_core_access;
|
||||
|
||||
public:
|
||||
|
||||
// Construction
|
||||
// ============
|
||||
|
||||
// Default constructor
|
||||
zip_iterator() { }
|
||||
|
||||
// Constructor from iterator tuple
|
||||
zip_iterator(IteratorTuple iterator_tuple)
|
||||
: m_iterator_tuple(iterator_tuple)
|
||||
{ }
|
||||
|
||||
// Copy constructor
|
||||
template<typename OtherIteratorTuple>
|
||||
zip_iterator(
|
||||
const zip_iterator<OtherIteratorTuple>& other,
|
||||
typename enable_if_convertible<
|
||||
OtherIteratorTuple,
|
||||
IteratorTuple
|
||||
>::type* = 0
|
||||
) : m_iterator_tuple(other.get_iterator_tuple())
|
||||
{}
|
||||
|
||||
// Get method for the iterator tuple.
|
||||
const IteratorTuple& get_iterator_tuple() const
|
||||
{ return m_iterator_tuple; }
|
||||
|
||||
private:
|
||||
|
||||
// Implementation of Iterator Operations
|
||||
// =====================================
|
||||
|
||||
// Dereferencing returns a tuple built from the dereferenced
|
||||
// iterators in the iterator tuple.
|
||||
typename super_t::reference dereference() const
|
||||
{
|
||||
typedef typename super_t::reference reference;
|
||||
typedef detail::converter<reference> gen;
|
||||
return gen::call(fusion::transform(
|
||||
get_iterator_tuple(),
|
||||
detail::dereference_iterator()));
|
||||
}
|
||||
|
||||
// Two zip iterators are equal if all iterators in the iterator
|
||||
// tuple are equal. NOTE: It should be possible to implement this
|
||||
// as
|
||||
//
|
||||
// return get_iterator_tuple() == other.get_iterator_tuple();
|
||||
//
|
||||
// but equality of tuples currently (7/2003) does not compile
|
||||
// under several compilers. No point in bringing in a bunch
|
||||
// of #ifdefs here.
|
||||
//
|
||||
template<typename OtherIteratorTuple>
|
||||
bool equal(const zip_iterator<OtherIteratorTuple>& other) const
|
||||
{
|
||||
return fusion::equal_to(
|
||||
get_iterator_tuple(),
|
||||
other.get_iterator_tuple());
|
||||
}
|
||||
|
||||
// Advancing a zip iterator means to advance all iterators in the
|
||||
// iterator tuple.
|
||||
void advance(typename super_t::difference_type n)
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::advance_iterator<BOOST_DEDUCED_TYPENAME super_t::difference_type>(n));
|
||||
}
|
||||
// Incrementing a zip iterator means to increment all iterators in
|
||||
// the iterator tuple.
|
||||
void increment()
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::increment_iterator());
|
||||
}
|
||||
|
||||
// Decrementing a zip iterator means to decrement all iterators in
|
||||
// the iterator tuple.
|
||||
void decrement()
|
||||
{
|
||||
fusion::for_each(
|
||||
m_iterator_tuple,
|
||||
detail::decrement_iterator());
|
||||
}
|
||||
|
||||
// Distance is calculated using the first iterator in the tuple.
|
||||
template<typename OtherIteratorTuple>
|
||||
typename super_t::difference_type distance_to(
|
||||
const zip_iterator<OtherIteratorTuple>& other
|
||||
) const
|
||||
{
|
||||
return fusion::at_c<0>(other.get_iterator_tuple()) -
|
||||
fusion::at_c<0>(this->get_iterator_tuple());
|
||||
}
|
||||
|
||||
// Data Members
|
||||
// ============
|
||||
|
||||
// The iterator tuple.
|
||||
IteratorTuple m_iterator_tuple;
|
||||
|
||||
};
|
||||
|
||||
// Make function for zip iterator
|
||||
//
|
||||
template<typename IteratorTuple>
|
||||
inline zip_iterator<IteratorTuple>
|
||||
make_zip_iterator(IteratorTuple t)
|
||||
{ return zip_iterator<IteratorTuple>(t); }
|
||||
|
||||
} // namespace iterators
|
||||
|
||||
using iterators::zip_iterator;
|
||||
using iterators::make_zip_iterator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
1327
boost/mp11/algorithm.hpp
Normal file
1327
boost/mp11/algorithm.hpp
Normal file
File diff suppressed because it is too large
Load Diff
111
boost/mp11/bind.hpp
Normal file
111
boost/mp11/bind.hpp
Normal file
@ -0,0 +1,111 @@
|
||||
#ifndef BOOST_MP11_BIND_HPP_INCLUDED
|
||||
#define BOOST_MP11_BIND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017, 2018 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_bind_front
|
||||
template<template<class...> class F, class... T> struct mp_bind_front
|
||||
{
|
||||
// the indirection through mp_defer works around the language inability
|
||||
// to expand U... into a fixed parameter list of an alias template
|
||||
|
||||
template<class... U> using fn = typename mp_defer<F, T..., U...>::type;
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>;
|
||||
|
||||
// mp_bind_back
|
||||
template<template<class...> class F, class... T> struct mp_bind_back
|
||||
{
|
||||
template<class... U> using fn = typename mp_defer<F, U..., T...>::type;
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>;
|
||||
|
||||
// mp_arg
|
||||
template<std::size_t I> struct mp_arg
|
||||
{
|
||||
template<class... T> using fn = mp_at_c<mp_list<T...>, I>;
|
||||
};
|
||||
|
||||
using _1 = mp_arg<0>;
|
||||
using _2 = mp_arg<1>;
|
||||
using _3 = mp_arg<2>;
|
||||
using _4 = mp_arg<3>;
|
||||
using _5 = mp_arg<4>;
|
||||
using _6 = mp_arg<5>;
|
||||
using _7 = mp_arg<6>;
|
||||
using _8 = mp_arg<7>;
|
||||
using _9 = mp_arg<8>;
|
||||
|
||||
// mp_bind
|
||||
template<template<class...> class F, class... T> struct mp_bind;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class V, class... T> struct eval_bound_arg
|
||||
{
|
||||
using type = V;
|
||||
};
|
||||
|
||||
template<std::size_t I, class... T> struct eval_bound_arg<mp_arg<I>, T...>
|
||||
{
|
||||
using type = typename mp_arg<I>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_front<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind_front<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_back<F, U...>, T...>
|
||||
{
|
||||
using type = typename mp_bind_back<F, U...>::template fn<T...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_bind
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 )
|
||||
private:
|
||||
|
||||
template<class... U> struct _f { using type = F<typename detail::eval_bound_arg<T, U...>::type...>; };
|
||||
|
||||
public:
|
||||
|
||||
template<class... U> using fn = typename _f<U...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class... U> using fn = F<typename detail::eval_bound_arg<T, U...>::type...>;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED
|
149
boost/mp11/detail/config.hpp
Normal file
149
boost/mp11/detail/config.hpp
Normal file
@ -0,0 +1,149 @@
|
||||
#ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
||||
|
||||
// Copyright 2016, 2018, 2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// BOOST_MP11_WORKAROUND
|
||||
|
||||
#if defined( BOOST_STRICT_CONFIG ) || defined( BOOST_MP11_NO_WORKAROUNDS )
|
||||
|
||||
# define BOOST_MP11_WORKAROUND( symbol, test ) 0
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_MP11_WORKAROUND( symbol, test ) ((symbol) != 0 && ((symbol) test))
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
#define BOOST_MP11_CUDA 0
|
||||
#define BOOST_MP11_CLANG 0
|
||||
#define BOOST_MP11_INTEL 0
|
||||
#define BOOST_MP11_GCC 0
|
||||
#define BOOST_MP11_MSVC 0
|
||||
|
||||
#define BOOST_MP11_CONSTEXPR constexpr
|
||||
|
||||
#if defined( __CUDACC__ )
|
||||
|
||||
// nvcc
|
||||
|
||||
# undef BOOST_MP11_CUDA
|
||||
# define BOOST_MP11_CUDA (__CUDACC_VER_MAJOR__ * 1000000 + __CUDACC_VER_MINOR__ * 10000 + __CUDACC_VER_BUILD__)
|
||||
|
||||
// CUDA (8.0) has no constexpr support in msvc mode:
|
||||
# if defined(_MSC_VER) && (BOOST_MP11_CUDA < 9000000)
|
||||
|
||||
# define BOOST_MP11_NO_CONSTEXPR
|
||||
|
||||
# undef BOOST_MP11_CONSTEXPR
|
||||
# define BOOST_MP11_CONSTEXPR
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__clang__)
|
||||
|
||||
// Clang
|
||||
|
||||
# undef BOOST_MP11_CLANG
|
||||
# define BOOST_MP11_CLANG (__clang_major__ * 100 + __clang_minor__)
|
||||
|
||||
# if defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(fallthrough) && __cplusplus >= 201406L // Clang 3.9+ in c++1z mode
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#if BOOST_MP11_CLANG < 400 && __cplusplus >= 201402L \
|
||||
&& defined( __GLIBCXX__ ) && !__has_include(<shared_mutex>)
|
||||
|
||||
// Clang pre-4 in C++14 mode, libstdc++ pre-4.9, ::gets is not defined,
|
||||
// but Clang tries to import it into std
|
||||
|
||||
extern "C" char *gets (char *__s);
|
||||
#endif
|
||||
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
|
||||
// Intel C++
|
||||
|
||||
# undef BOOST_MP11_INTEL
|
||||
# define BOOST_MP11_INTEL __INTEL_COMPILER
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
// g++
|
||||
|
||||
# undef BOOST_MP11_GCC
|
||||
# define BOOST_MP11_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
// MS Visual C++
|
||||
|
||||
# undef BOOST_MP11_MSVC
|
||||
# define BOOST_MP11_MSVC _MSC_VER
|
||||
|
||||
# if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
# define BOOST_MP11_NO_CONSTEXPR
|
||||
# endif
|
||||
|
||||
#if _MSC_FULL_VER < 190024210 // 2015u3
|
||||
# undef BOOST_MP11_CONSTEXPR
|
||||
# define BOOST_MP11_CONSTEXPR
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_CXX14_CONSTEXPR
|
||||
|
||||
#if !defined(BOOST_MP11_NO_CONSTEXPR) && defined(__cpp_constexpr) && __cpp_constexpr >= 201304
|
||||
# define BOOST_MP11_HAS_CXX14_CONSTEXPR
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
|
||||
#if !defined(BOOST_MP11_HAS_FOLD_EXPRESSIONS) && defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603
|
||||
# define BOOST_MP11_HAS_FOLD_EXPRESSIONS
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_TYPE_PACK_ELEMENT
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__type_pack_element)
|
||||
# define BOOST_MP11_HAS_TYPE_PACK_ELEMENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
|
||||
#if defined(__cpp_nontype_template_parameter_auto) && __cpp_nontype_template_parameter_auto >= 201606L
|
||||
# define BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
#endif
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
// mp_value<0> is bool, mp_value<-1L> is int, etc
|
||||
# undef BOOST_MP11_HAS_TEMPLATE_AUTO
|
||||
#endif
|
||||
|
||||
// BOOST_MP11_DEPRECATED(msg)
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, < 304 )
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
# define BOOST_MP11_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
# define BOOST_MP11_DEPRECATED(msg) [[deprecated(msg)]]
|
||||
#else
|
||||
# define BOOST_MP11_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_CONFIG_HPP_INCLUDED
|
321
boost/mp11/detail/mp_append.hpp
Normal file
321
boost/mp11/detail/mp_append.hpp
Normal file
@ -0,0 +1,321 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/mp_count.hpp>
|
||||
#include <boost/mp11/detail/mp_is_value_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list_v.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_append<L...>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// append_type_lists
|
||||
|
||||
template<class... L> struct mp_append_impl;
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<class... L> struct mp_append_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_append_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_append_impl<L<T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_append_impl<L1<T1...>, L2<T2...>>
|
||||
{
|
||||
using type = L1<T1..., T2...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, template<class...> class L5, class... T5, class... Lr> struct mp_append_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, Lr...>
|
||||
{
|
||||
using type = typename mp_append_impl<L1<T1..., T2..., T3..., T4..., T5...>, Lr...>::type;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class L1 = mp_list<>, class L2 = mp_list<>, class L3 = mp_list<>, class L4 = mp_list<>, class L5 = mp_list<>, class L6 = mp_list<>, class L7 = mp_list<>, class L8 = mp_list<>, class L9 = mp_list<>, class L10 = mp_list<>, class L11 = mp_list<>> struct append_11_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
template<class...> class L1, class... T1,
|
||||
template<class...> class L2, class... T2,
|
||||
template<class...> class L3, class... T3,
|
||||
template<class...> class L4, class... T4,
|
||||
template<class...> class L5, class... T5,
|
||||
template<class...> class L6, class... T6,
|
||||
template<class...> class L7, class... T7,
|
||||
template<class...> class L8, class... T8,
|
||||
template<class...> class L9, class... T9,
|
||||
template<class...> class L10, class... T10,
|
||||
template<class...> class L11, class... T11>
|
||||
|
||||
struct append_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00 = mp_list<>, class L01 = mp_list<>, class L02 = mp_list<>, class L03 = mp_list<>, class L04 = mp_list<>, class L05 = mp_list<>, class L06 = mp_list<>, class L07 = mp_list<>, class L08 = mp_list<>, class L09 = mp_list<>, class L0A = mp_list<>,
|
||||
class L10 = mp_list<>, class L11 = mp_list<>, class L12 = mp_list<>, class L13 = mp_list<>, class L14 = mp_list<>, class L15 = mp_list<>, class L16 = mp_list<>, class L17 = mp_list<>, class L18 = mp_list<>, class L19 = mp_list<>,
|
||||
class L20 = mp_list<>, class L21 = mp_list<>, class L22 = mp_list<>, class L23 = mp_list<>, class L24 = mp_list<>, class L25 = mp_list<>, class L26 = mp_list<>, class L27 = mp_list<>, class L28 = mp_list<>, class L29 = mp_list<>,
|
||||
class L30 = mp_list<>, class L31 = mp_list<>, class L32 = mp_list<>, class L33 = mp_list<>, class L34 = mp_list<>, class L35 = mp_list<>, class L36 = mp_list<>, class L37 = mp_list<>, class L38 = mp_list<>, class L39 = mp_list<>,
|
||||
class L40 = mp_list<>, class L41 = mp_list<>, class L42 = mp_list<>, class L43 = mp_list<>, class L44 = mp_list<>, class L45 = mp_list<>, class L46 = mp_list<>, class L47 = mp_list<>, class L48 = mp_list<>, class L49 = mp_list<>,
|
||||
class L50 = mp_list<>, class L51 = mp_list<>, class L52 = mp_list<>, class L53 = mp_list<>, class L54 = mp_list<>, class L55 = mp_list<>, class L56 = mp_list<>, class L57 = mp_list<>, class L58 = mp_list<>, class L59 = mp_list<>,
|
||||
class L60 = mp_list<>, class L61 = mp_list<>, class L62 = mp_list<>, class L63 = mp_list<>, class L64 = mp_list<>, class L65 = mp_list<>, class L66 = mp_list<>, class L67 = mp_list<>, class L68 = mp_list<>, class L69 = mp_list<>,
|
||||
class L70 = mp_list<>, class L71 = mp_list<>, class L72 = mp_list<>, class L73 = mp_list<>, class L74 = mp_list<>, class L75 = mp_list<>, class L76 = mp_list<>, class L77 = mp_list<>, class L78 = mp_list<>, class L79 = mp_list<>,
|
||||
class L80 = mp_list<>, class L81 = mp_list<>, class L82 = mp_list<>, class L83 = mp_list<>, class L84 = mp_list<>, class L85 = mp_list<>, class L86 = mp_list<>, class L87 = mp_list<>, class L88 = mp_list<>, class L89 = mp_list<>,
|
||||
class L90 = mp_list<>, class L91 = mp_list<>, class L92 = mp_list<>, class L93 = mp_list<>, class L94 = mp_list<>, class L95 = mp_list<>, class L96 = mp_list<>, class L97 = mp_list<>, class L98 = mp_list<>, class L99 = mp_list<>,
|
||||
class LA0 = mp_list<>, class LA1 = mp_list<>, class LA2 = mp_list<>, class LA3 = mp_list<>, class LA4 = mp_list<>, class LA5 = mp_list<>, class LA6 = mp_list<>, class LA7 = mp_list<>, class LA8 = mp_list<>, class LA9 = mp_list<>
|
||||
|
||||
> struct append_111_impl
|
||||
{
|
||||
using type = typename append_11_impl<
|
||||
|
||||
typename append_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
|
||||
typename append_11_impl<mp_list<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
|
||||
typename append_11_impl<mp_list<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
|
||||
typename append_11_impl<mp_list<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
|
||||
typename append_11_impl<mp_list<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
|
||||
typename append_11_impl<mp_list<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
|
||||
typename append_11_impl<mp_list<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
|
||||
typename append_11_impl<mp_list<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
|
||||
typename append_11_impl<mp_list<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
|
||||
typename append_11_impl<mp_list<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
|
||||
typename append_11_impl<mp_list<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
|
||||
|
||||
>::type;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
|
||||
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
|
||||
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
|
||||
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
|
||||
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
|
||||
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
|
||||
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
|
||||
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
|
||||
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
|
||||
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
|
||||
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
|
||||
class... Lr
|
||||
|
||||
> struct append_inf_impl
|
||||
{
|
||||
using prefix = typename append_111_impl<
|
||||
|
||||
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
|
||||
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
|
||||
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
|
||||
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
|
||||
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
|
||||
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
|
||||
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
|
||||
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
|
||||
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
|
||||
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
|
||||
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
|
||||
|
||||
>::type;
|
||||
|
||||
using type = typename mp_append_impl<prefix, Lr...>::type;
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<class... L>
|
||||
struct mp_append_impl_cuda_workaround
|
||||
{
|
||||
using type = mp_if_c<(sizeof...(L) > 111), mp_quote<append_inf_impl>, mp_if_c<(sizeof...(L) > 11), mp_quote<append_111_impl>, mp_quote<append_11_impl> > >;
|
||||
};
|
||||
|
||||
template<class... L> struct mp_append_impl: mp_append_impl_cuda_workaround<L...>::type::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class... L> struct mp_append_impl:
|
||||
mp_cond<
|
||||
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_inf_impl>,
|
||||
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_111_impl>,
|
||||
mp_true, mp_quote<append_11_impl>
|
||||
>::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
#endif // #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
struct append_type_lists
|
||||
{
|
||||
template<class... L> using fn = typename mp_append_impl<L...>::type;
|
||||
};
|
||||
|
||||
// append_value_lists
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<class... L> struct append_value_impl;
|
||||
|
||||
template<class L1 = mp_list_v<>, class L2 = mp_list_v<>, class L3 = mp_list_v<>, class L4 = mp_list_v<>, class L5 = mp_list_v<>, class L6 = mp_list_v<>, class L7 = mp_list_v<>, class L8 = mp_list_v<>, class L9 = mp_list_v<>, class L10 = mp_list_v<>, class L11 = mp_list_v<>> struct append_value_11_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
template<auto...> class L1, auto... T1,
|
||||
template<auto...> class L2, auto... T2,
|
||||
template<auto...> class L3, auto... T3,
|
||||
template<auto...> class L4, auto... T4,
|
||||
template<auto...> class L5, auto... T5,
|
||||
template<auto...> class L6, auto... T6,
|
||||
template<auto...> class L7, auto... T7,
|
||||
template<auto...> class L8, auto... T8,
|
||||
template<auto...> class L9, auto... T9,
|
||||
template<auto...> class L10, auto... T10,
|
||||
template<auto...> class L11, auto... T11>
|
||||
|
||||
struct append_value_11_impl<L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L5<T5...>, L6<T6...>, L7<T7...>, L8<T8...>, L9<T9...>, L10<T10...>, L11<T11...>>
|
||||
{
|
||||
using type = L1<T1..., T2..., T3..., T4..., T5..., T6..., T7..., T8..., T9..., T10..., T11...>;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00 = mp_list_v<>, class L01 = mp_list_v<>, class L02 = mp_list_v<>, class L03 = mp_list_v<>, class L04 = mp_list_v<>, class L05 = mp_list_v<>, class L06 = mp_list_v<>, class L07 = mp_list_v<>, class L08 = mp_list_v<>, class L09 = mp_list_v<>, class L0A = mp_list_v<>,
|
||||
class L10 = mp_list_v<>, class L11 = mp_list_v<>, class L12 = mp_list_v<>, class L13 = mp_list_v<>, class L14 = mp_list_v<>, class L15 = mp_list_v<>, class L16 = mp_list_v<>, class L17 = mp_list_v<>, class L18 = mp_list_v<>, class L19 = mp_list_v<>,
|
||||
class L20 = mp_list_v<>, class L21 = mp_list_v<>, class L22 = mp_list_v<>, class L23 = mp_list_v<>, class L24 = mp_list_v<>, class L25 = mp_list_v<>, class L26 = mp_list_v<>, class L27 = mp_list_v<>, class L28 = mp_list_v<>, class L29 = mp_list_v<>,
|
||||
class L30 = mp_list_v<>, class L31 = mp_list_v<>, class L32 = mp_list_v<>, class L33 = mp_list_v<>, class L34 = mp_list_v<>, class L35 = mp_list_v<>, class L36 = mp_list_v<>, class L37 = mp_list_v<>, class L38 = mp_list_v<>, class L39 = mp_list_v<>,
|
||||
class L40 = mp_list_v<>, class L41 = mp_list_v<>, class L42 = mp_list_v<>, class L43 = mp_list_v<>, class L44 = mp_list_v<>, class L45 = mp_list_v<>, class L46 = mp_list_v<>, class L47 = mp_list_v<>, class L48 = mp_list_v<>, class L49 = mp_list_v<>,
|
||||
class L50 = mp_list_v<>, class L51 = mp_list_v<>, class L52 = mp_list_v<>, class L53 = mp_list_v<>, class L54 = mp_list_v<>, class L55 = mp_list_v<>, class L56 = mp_list_v<>, class L57 = mp_list_v<>, class L58 = mp_list_v<>, class L59 = mp_list_v<>,
|
||||
class L60 = mp_list_v<>, class L61 = mp_list_v<>, class L62 = mp_list_v<>, class L63 = mp_list_v<>, class L64 = mp_list_v<>, class L65 = mp_list_v<>, class L66 = mp_list_v<>, class L67 = mp_list_v<>, class L68 = mp_list_v<>, class L69 = mp_list_v<>,
|
||||
class L70 = mp_list_v<>, class L71 = mp_list_v<>, class L72 = mp_list_v<>, class L73 = mp_list_v<>, class L74 = mp_list_v<>, class L75 = mp_list_v<>, class L76 = mp_list_v<>, class L77 = mp_list_v<>, class L78 = mp_list_v<>, class L79 = mp_list_v<>,
|
||||
class L80 = mp_list_v<>, class L81 = mp_list_v<>, class L82 = mp_list_v<>, class L83 = mp_list_v<>, class L84 = mp_list_v<>, class L85 = mp_list_v<>, class L86 = mp_list_v<>, class L87 = mp_list_v<>, class L88 = mp_list_v<>, class L89 = mp_list_v<>,
|
||||
class L90 = mp_list_v<>, class L91 = mp_list_v<>, class L92 = mp_list_v<>, class L93 = mp_list_v<>, class L94 = mp_list_v<>, class L95 = mp_list_v<>, class L96 = mp_list_v<>, class L97 = mp_list_v<>, class L98 = mp_list_v<>, class L99 = mp_list_v<>,
|
||||
class LA0 = mp_list_v<>, class LA1 = mp_list_v<>, class LA2 = mp_list_v<>, class LA3 = mp_list_v<>, class LA4 = mp_list_v<>, class LA5 = mp_list_v<>, class LA6 = mp_list_v<>, class LA7 = mp_list_v<>, class LA8 = mp_list_v<>, class LA9 = mp_list_v<>
|
||||
|
||||
> struct append_value_111_impl
|
||||
{
|
||||
using type = typename append_value_11_impl<
|
||||
|
||||
typename append_value_11_impl<L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L10, L11, L12, L13, L14, L15, L16, L17, L18, L19>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L20, L21, L22, L23, L24, L25, L26, L27, L28, L29>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L30, L31, L32, L33, L34, L35, L36, L37, L38, L39>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L40, L41, L42, L43, L44, L45, L46, L47, L48, L49>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L50, L51, L52, L53, L54, L55, L56, L57, L58, L59>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L60, L61, L62, L63, L64, L65, L66, L67, L68, L69>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L70, L71, L72, L73, L74, L75, L76, L77, L78, L79>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L80, L81, L82, L83, L84, L85, L86, L87, L88, L89>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, L90, L91, L92, L93, L94, L95, L96, L97, L98, L99>::type,
|
||||
typename append_value_11_impl<mp_list_v<>, LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9>::type
|
||||
|
||||
>::type;
|
||||
};
|
||||
|
||||
template<
|
||||
|
||||
class L00, class L01, class L02, class L03, class L04, class L05, class L06, class L07, class L08, class L09, class L0A,
|
||||
class L10, class L11, class L12, class L13, class L14, class L15, class L16, class L17, class L18, class L19,
|
||||
class L20, class L21, class L22, class L23, class L24, class L25, class L26, class L27, class L28, class L29,
|
||||
class L30, class L31, class L32, class L33, class L34, class L35, class L36, class L37, class L38, class L39,
|
||||
class L40, class L41, class L42, class L43, class L44, class L45, class L46, class L47, class L48, class L49,
|
||||
class L50, class L51, class L52, class L53, class L54, class L55, class L56, class L57, class L58, class L59,
|
||||
class L60, class L61, class L62, class L63, class L64, class L65, class L66, class L67, class L68, class L69,
|
||||
class L70, class L71, class L72, class L73, class L74, class L75, class L76, class L77, class L78, class L79,
|
||||
class L80, class L81, class L82, class L83, class L84, class L85, class L86, class L87, class L88, class L89,
|
||||
class L90, class L91, class L92, class L93, class L94, class L95, class L96, class L97, class L98, class L99,
|
||||
class LA0, class LA1, class LA2, class LA3, class LA4, class LA5, class LA6, class LA7, class LA8, class LA9,
|
||||
class... Lr
|
||||
|
||||
> struct append_value_inf_impl
|
||||
{
|
||||
using prefix = typename append_value_111_impl<
|
||||
|
||||
L00, L01, L02, L03, L04, L05, L06, L07, L08, L09, L0A,
|
||||
L10, L11, L12, L13, L14, L15, L16, L17, L18, L19,
|
||||
L20, L21, L22, L23, L24, L25, L26, L27, L28, L29,
|
||||
L30, L31, L32, L33, L34, L35, L36, L37, L38, L39,
|
||||
L40, L41, L42, L43, L44, L45, L46, L47, L48, L49,
|
||||
L50, L51, L52, L53, L54, L55, L56, L57, L58, L59,
|
||||
L60, L61, L62, L63, L64, L65, L66, L67, L68, L69,
|
||||
L70, L71, L72, L73, L74, L75, L76, L77, L78, L79,
|
||||
L80, L81, L82, L83, L84, L85, L86, L87, L88, L89,
|
||||
L90, L91, L92, L93, L94, L95, L96, L97, L98, L99,
|
||||
LA0, LA1, LA2, LA3, LA4, LA5, LA6, LA7, LA8, LA9
|
||||
|
||||
>::type;
|
||||
|
||||
using type = typename append_value_impl<prefix, Lr...>::type;
|
||||
};
|
||||
|
||||
template<class... L> struct append_value_impl:
|
||||
mp_cond<
|
||||
mp_bool<(sizeof...(L) > 111)>, mp_quote<append_value_inf_impl>,
|
||||
mp_bool<(sizeof...(L) > 11)>, mp_quote<append_value_111_impl>,
|
||||
mp_true, mp_quote<append_value_11_impl>
|
||||
>::template fn<L...>
|
||||
{
|
||||
};
|
||||
|
||||
struct append_value_lists
|
||||
{
|
||||
template<class... L> using fn = typename append_value_impl<L...>::type;
|
||||
};
|
||||
|
||||
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<class... L> using mp_append = typename mp_if_c<(sizeof...(L) > 0 && sizeof...(L) == mp_count_if<mp_list<L...>, mp_is_value_list>::value), detail::append_value_lists, detail::append_type_lists>::template fn<L...>;
|
||||
|
||||
#else
|
||||
|
||||
template<class... L> using mp_append = detail::append_type_lists::fn<L...>;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_APPEND_HPP_INCLUDED
|
48
boost/mp11/detail/mp_copy_if.hpp
Normal file
48
boost/mp11/detail/mp_copy_if.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_copy_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_copy_if_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_copy_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
template<class U> struct _f { using type = mp_if<P<U>, mp_list<U>, mp_list<>>; };
|
||||
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||
#else
|
||||
template<class U> using _f = mp_if<P<U>, mp_list<U>, mp_list<>>;
|
||||
using type = mp_append<L<>, _f<T>...>;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_copy_if = typename detail::mp_copy_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_copy_if_q = mp_copy_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_COPY_IF_HPP_INCLUDED
|
147
boost/mp11/detail/mp_count.hpp
Normal file
147
boost/mp11/detail/mp_count.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2016 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_count<L, V>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
constexpr std::size_t cx_plus()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T1, class... T> constexpr std::size_t cx_plus(T1 t1, T... t)
|
||||
{
|
||||
return static_cast<std::size_t>(t1) + cx_plus(t...);
|
||||
}
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T>
|
||||
constexpr std::size_t cx_plus(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T... t)
|
||||
{
|
||||
return static_cast<std::size_t>(t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8 + t9 + t10) + cx_plus(t...);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<class L, class V> struct mp_count_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
||||
|
||||
template<class V, class... T> constexpr std::size_t cx_count()
|
||||
{
|
||||
constexpr bool a[] = { false, std::is_same<T, V>::value... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_count<V, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<cx_plus(std::is_same<T, V>::value...)>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_size_t<mp_plus<std::is_same<T, V>...>::value>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class V> using mp_count = typename detail::mp_count_impl<L, V>::type;
|
||||
|
||||
// mp_count_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_count_if_impl;
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<template<class...> class P, class... T> constexpr std::size_t cx_count_if()
|
||||
{
|
||||
constexpr bool a[] = { false, static_cast<bool>( P<T>::value )... };
|
||||
|
||||
std::size_t r = 0;
|
||||
|
||||
for( std::size_t i = 1; i < sizeof...(T) + 1; ++i )
|
||||
{
|
||||
r += a[ i ];
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
using type = mp_size_t<cx_count_if<P, T...>()>;
|
||||
};
|
||||
|
||||
#elif !defined( BOOST_MP11_NO_CONSTEXPR )
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
using type = mp_size_t<cx_plus(mp_to_bool<P<T>>::value...)>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_count_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
|
||||
template<class T> struct _f { using type = mp_to_bool<P<T>>; };
|
||||
using type = mp_size_t<mp_plus<typename _f<T>::type...>::value>;
|
||||
|
||||
#else
|
||||
|
||||
using type = mp_size_t<mp_plus<mp_to_bool<P<T>>...>::value>;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_count_if = typename detail::mp_count_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_COUNT_HPP_INCLUDED
|
119
boost/mp11/detail/mp_defer.hpp
Normal file
119
boost/mp11/detail/mp_defer.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2020, 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_if, mp_if_c
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool C, class T, class... E> struct mp_if_c_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class... E> struct mp_if_c_impl<true, T, E...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, class E> struct mp_if_c_impl<false, T, E>
|
||||
{
|
||||
using type = E;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
|
||||
template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
|
||||
|
||||
// mp_valid
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_INTEL, != 0 ) // tested at 1800
|
||||
|
||||
// contributed by Roland Schulz in https://github.com/boostorg/mp11/issues/17
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class...> using void_t = void;
|
||||
|
||||
template<class, template<class...> class F, class... T>
|
||||
struct mp_valid_impl: mp_false {};
|
||||
|
||||
template<template<class...> class F, class... T>
|
||||
struct mp_valid_impl<void_t<F<T...>>, F, T...>: mp_true {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<void, F, T...>;
|
||||
|
||||
#else
|
||||
|
||||
// implementation by Bruno Dutra (by the name is_evaluable)
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_valid_impl
|
||||
{
|
||||
template<template<class...> class G, class = G<T...>> static mp_true check(int);
|
||||
template<template<class...> class> static mp_false check(...);
|
||||
|
||||
using type = decltype(check<F>(0));
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
|
||||
|
||||
#endif
|
||||
|
||||
template<class Q, class... T> using mp_valid_q = mp_valid<Q::template fn, T...>;
|
||||
|
||||
// mp_defer
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_defer_impl
|
||||
{
|
||||
using type = F<T...>;
|
||||
};
|
||||
|
||||
struct mp_no_type
|
||||
{
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<template<class...> class F, class... T> struct mp_defer_cuda_workaround
|
||||
{
|
||||
using type = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_CUDA, >= 9000000 && BOOST_MP11_CUDA < 10000000 )
|
||||
|
||||
template<template<class...> class F, class... T> using mp_defer = typename detail::mp_defer_cuda_workaround< F, T...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_DEFER_HPP_INCLUDED
|
164
boost/mp11/detail/mp_fold.hpp
Normal file
164
boost/mp11/detail/mp_fold.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <boost/mp11/detail/mp_defer.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_fold<L, V, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class V, template<class...> class F> struct mp_fold_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_fold is not a list
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1800 )
|
||||
|
||||
template<template<class...> class L, class... T, class V, template<class...> class F> struct mp_fold_impl<L<T...>, V, F>
|
||||
{
|
||||
static_assert( sizeof...(T) == 0, "T... must be empty" );
|
||||
using type = V;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<template<class...> class L, class V, template<class...> class F> struct mp_fold_impl<L<>, V, F>
|
||||
{
|
||||
using type = V;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q1
|
||||
{
|
||||
template<class T1>
|
||||
using fn = F<V, T1>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q2
|
||||
{
|
||||
template<class T1, class T2>
|
||||
using fn = F<F<V, T1>, T2>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q3
|
||||
{
|
||||
template<class T1, class T2, class T3>
|
||||
using fn = F<F<F<V, T1>, T2>, T3>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q4
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4>
|
||||
using fn = F<F<F<F<V, T1>, T2>, T3>, T4>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q5
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5>
|
||||
using fn = F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q6
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
using fn = F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q7
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
||||
using fn = F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q8
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8>
|
||||
using fn = F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>;
|
||||
};
|
||||
|
||||
template<class V, template<class...> class F> struct mp_fold_Q9
|
||||
{
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
|
||||
using fn = F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template<template<class...> class L, class T1, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1>, V, F>: mp_defer<mp_fold_Q1<V, F>::template fn, T1>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2>, V, F>: mp_defer<mp_fold_Q2<V, F>::template fn, T1, T2>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3>, V, F>: mp_defer<mp_fold_Q3<V, F>::template fn, T1, T2, T3>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4>, V, F>: mp_defer<mp_fold_Q4<V, F>::template fn, T1, T2, T3, T4>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5>, V, F>: mp_defer<mp_fold_Q5<V, F>::template fn, T1, T2, T3, T4, T5>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6>, V, F>: mp_defer<mp_fold_Q6<V, F>::template fn, T1, T2, T3, T4, T5, T6>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7>, V, F>: mp_defer<mp_fold_Q7<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8>, V, F>: mp_defer<mp_fold_Q8<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8>
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9>, V, F>: mp_defer<mp_fold_Q9<V, F>::template fn, T1, T2, T3, T4, T5, T6, T7, T8, T9>
|
||||
{
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T, class V, template<class...> class F>
|
||||
struct mp_fold_impl<L<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>, V, F>
|
||||
{
|
||||
using type = typename mp_fold_impl<L<T...>, F<F<F<F<F<F<F<F<F<F<V, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>, T10>, F>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
|
||||
template<class L, class V, class Q> using mp_fold_q = mp_fold<L, V, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_FOLD_HPP_INCLUDED
|
50
boost/mp11/detail/mp_front.hpp
Normal file
50
boost/mp11/detail/mp_front.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/mp_value.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = T1;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A> struct mp_front_impl<L<A1, A...>>
|
||||
{
|
||||
using type = mp_value<A1>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_front = typename detail::mp_front_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_FRONT_HPP_INCLUDED
|
39
boost/mp11/detail/mp_is_list.hpp
Normal file
39
boost/mp11/detail/mp_is_list.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_is_list<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_is_list_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_is_list_impl<L<T...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_is_list = typename detail::mp_is_list_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_LIST_HPP_INCLUDED
|
41
boost/mp11/detail/mp_is_value_list.hpp
Normal file
41
boost/mp11/detail/mp_is_value_list.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_is_value_list<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_is_value_list_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A> struct mp_is_value_list_impl<L<A...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_is_value_list = typename detail::mp_is_value_list_impl<L>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_IS_VALUE_LIST_HPP_INCLUDED
|
24
boost/mp11/detail/mp_list.hpp
Normal file
24
boost/mp11/detail/mp_list.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2016 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_list<T...>
|
||||
template<class... T> struct mp_list
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_HPP_INCLUDED
|
27
boost/mp11/detail/mp_list_v.hpp
Normal file
27
boost/mp11/detail/mp_list_v.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
// mp_list_v<A...>
|
||||
template<auto... A> struct mp_list_v
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_LIST_V_HPP_INCLUDED
|
87
boost/mp11/detail/mp_map_find.hpp
Normal file
87
boost/mp11/detail/mp_map_find.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
// not exactly good practice, but...
|
||||
namespace std
|
||||
{
|
||||
template<class... _Types> class tuple;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_map_find
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<class T> using mpmf_wrap = mp_identity<T>;
|
||||
template<class T> using mpmf_unwrap = typename T::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mpmf_tuple {};
|
||||
|
||||
template<class T> struct mpmf_wrap_impl
|
||||
{
|
||||
using type = mp_identity<T>;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_wrap_impl< std::tuple<T...> >
|
||||
{
|
||||
using type = mp_identity< mpmf_tuple<T...> >;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_wrap = typename mpmf_wrap_impl<T>::type;
|
||||
|
||||
template<class T> struct mpmf_unwrap_impl
|
||||
{
|
||||
using type = typename T::type;
|
||||
};
|
||||
|
||||
template<class... T> struct mpmf_unwrap_impl< mp_identity< mpmf_tuple<T...> > >
|
||||
{
|
||||
using type = std::tuple<T...>;
|
||||
};
|
||||
|
||||
template<class T> using mpmf_unwrap = typename mpmf_unwrap_impl<T>::type;
|
||||
|
||||
#endif // #if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1930 )
|
||||
|
||||
template<class M, class K> struct mp_map_find_impl;
|
||||
|
||||
template<template<class...> class M, class... T, class K> struct mp_map_find_impl<M<T...>, K>
|
||||
{
|
||||
using U = mp_inherit<mpmf_wrap<T>...>;
|
||||
|
||||
template<template<class...> class L, class... U> static mp_identity<L<K, U...>> f( mp_identity<L<K, U...>>* );
|
||||
static mp_identity<void> f( ... );
|
||||
|
||||
using type = mpmf_unwrap< decltype( f( static_cast<U*>(0) ) ) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class M, class K> using mp_map_find = typename detail::mp_map_find_impl<M, K>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MAP_FIND_HPP_INCLUDED
|
51
boost/mp11/detail/mp_min_element.hpp
Normal file
51
boost/mp11/detail/mp_min_element.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/mp_fold.hpp>
|
||||
#include <boost/mp11/list.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_min_element<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class P> struct select_min
|
||||
{
|
||||
template<class T1, class T2> using fn = mp_if<P<T1, T2>, T1, T2>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_min_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_min<P>>;
|
||||
template<class L, class Q> using mp_min_element_q = mp_min_element<L, Q::template fn>;
|
||||
|
||||
// mp_max_element<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<template<class...> class P> struct select_max
|
||||
{
|
||||
template<class T1, class T2> using fn = mp_if<P<T2, T1>, T1, T2>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_max_element = mp_fold_q<mp_rest<L>, mp_first<L>, detail::select_max<P>>;
|
||||
template<class L, class Q> using mp_max_element_q = mp_max_element<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_MIN_ELEMENT_HPP_INCLUDED
|
84
boost/mp11/detail/mp_plus.hpp
Normal file
84
boost/mp11/detail/mp_plus.hpp
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_plus
|
||||
namespace detail
|
||||
{
|
||||
|
||||
#if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_CLANG, != 0 )
|
||||
|
||||
// msvc fails with parser stack overflow for large sizeof...(T)
|
||||
// clang exceeds -fbracket-depth, which defaults to 256
|
||||
|
||||
template<class... T> struct mp_plus_impl
|
||||
{
|
||||
static const auto _v = (T::value + ... + 0);
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> struct mp_plus_impl;
|
||||
|
||||
template<> struct mp_plus_impl<>
|
||||
{
|
||||
using type = std::integral_constant<int, 0>;
|
||||
};
|
||||
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 40800 )
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const decltype(T1::value + mp_plus_impl<T...>::type::value) _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const
|
||||
decltype(T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value)
|
||||
_v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<class T1, class... T> struct mp_plus_impl<T1, T...>
|
||||
{
|
||||
static const auto _v = T1::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class... T> struct mp_plus_impl<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T...>
|
||||
{
|
||||
static const auto _v = T1::value + T2::value + T3::value + T4::value + T5::value + T6::value + T7::value + T8::value + T9::value + T10::value + mp_plus_impl<T...>::type::value;
|
||||
using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_plus = typename detail::mp_plus_impl<T...>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_PLUS_HPP_INCLUDED
|
48
boost/mp11/detail/mp_remove_if.hpp
Normal file
48
boost/mp11/detail/mp_remove_if.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_remove_if<L, P>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class P> struct mp_remove_if_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class P> struct mp_remove_if_impl<L<T...>, P>
|
||||
{
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 )
|
||||
template<class U> struct _f { using type = mp_if<P<U>, mp_list<>, mp_list<U>>; };
|
||||
using type = mp_append<L<>, typename _f<T>::type...>;
|
||||
#else
|
||||
template<class U> using _f = mp_if<P<U>, mp_list<>, mp_list<U>>;
|
||||
using type = mp_append<L<>, _f<T>...>;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class P> using mp_remove_if = typename detail::mp_remove_if_impl<L, P>::type;
|
||||
template<class L, class Q> using mp_remove_if_q = mp_remove_if<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_REMOVE_IF_HPP_INCLUDED
|
54
boost/mp11/detail/mp_rename.hpp
Normal file
54
boost/mp11/detail/mp_rename.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/mp_defer.hpp>
|
||||
#include <boost/mp11/detail/mp_value.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_rename<L, B>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class B> struct mp_rename_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<class...> class B> struct mp_rename_impl<L<T...>, B>: mp_defer<B, T...>
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, template<class...> class B> struct mp_rename_impl<L<A...>, B>: mp_defer<B, mp_value<A>...>
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class B> using mp_rename = typename detail::mp_rename_impl<L, B>::type;
|
||||
|
||||
// mp_apply<F, L>
|
||||
template<template<class...> class F, class L> using mp_apply = typename detail::mp_rename_impl<L, F>::type;
|
||||
|
||||
// mp_apply_q<Q, L>
|
||||
template<class Q, class L> using mp_apply_q = typename detail::mp_rename_impl<L, Q::template fn>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_RENAME_HPP_INCLUDED
|
25
boost/mp11/detail/mp_value.hpp
Normal file
25
boost/mp11/detail/mp_value.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2023 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
template<auto A> using mp_value = std::integral_constant<decltype(A), A>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_VALUE_HPP_INCLUDED
|
32
boost/mp11/detail/mp_void.hpp
Normal file
32
boost/mp11/detail/mp_void.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_void<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_void_impl
|
||||
{
|
||||
using type = void;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_void = typename detail::mp_void_impl<T...>::type;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_VOID_HPP_INCLUDED
|
385
boost/mp11/detail/mp_with_index.hpp
Normal file
385
boost/mp11/detail/mp_with_index.hpp
Normal file
@ -0,0 +1,385 @@
|
||||
#ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
||||
#define BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
||||
|
||||
// Copyright 2017 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#if defined( BOOST_MP11_HAS_CXX14_CONSTEXPR )
|
||||
# define BOOST_MP11_CONSTEXPR14 constexpr
|
||||
#else
|
||||
# define BOOST_MP11_CONSTEXPR14
|
||||
#endif
|
||||
|
||||
#if defined( __GNUC__ ) || defined( __clang__ )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __builtin_unreachable();
|
||||
#elif defined( _MSC_VER )
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT default: __assume(false);
|
||||
#else
|
||||
# define BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<std::size_t N> struct mp_with_index_impl_
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
if( i < N / 2 )
|
||||
{
|
||||
return mp_with_index_impl_<N/2>::template call<K>( i, std::forward<F>(f) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return mp_with_index_impl_<N-N/2>::template call<K+N/2>( i - N/2, std::forward<F>(f) );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<0>
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<1>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t /*i*/, F && f )
|
||||
{
|
||||
return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<2>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<3>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<4>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<5>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<6>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<7>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<8>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<9>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<10>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<11>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<12>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<13>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<14>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<15>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct mp_with_index_impl_<16>
|
||||
{
|
||||
template<std::size_t K, class F> static BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) call( std::size_t i, F && f )
|
||||
{
|
||||
switch( i )
|
||||
{
|
||||
BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
case 0: return std::forward<F>(f)( mp_size_t<K+0>() );
|
||||
case 1: return std::forward<F>(f)( mp_size_t<K+1>() );
|
||||
case 2: return std::forward<F>(f)( mp_size_t<K+2>() );
|
||||
case 3: return std::forward<F>(f)( mp_size_t<K+3>() );
|
||||
case 4: return std::forward<F>(f)( mp_size_t<K+4>() );
|
||||
case 5: return std::forward<F>(f)( mp_size_t<K+5>() );
|
||||
case 6: return std::forward<F>(f)( mp_size_t<K+6>() );
|
||||
case 7: return std::forward<F>(f)( mp_size_t<K+7>() );
|
||||
case 8: return std::forward<F>(f)( mp_size_t<K+8>() );
|
||||
case 9: return std::forward<F>(f)( mp_size_t<K+9>() );
|
||||
case 10: return std::forward<F>(f)( mp_size_t<K+10>() );
|
||||
case 11: return std::forward<F>(f)( mp_size_t<K+11>() );
|
||||
case 12: return std::forward<F>(f)( mp_size_t<K+12>() );
|
||||
case 13: return std::forward<F>(f)( mp_size_t<K+13>() );
|
||||
case 14: return std::forward<F>(f)( mp_size_t<K+14>() );
|
||||
case 15: return std::forward<F>(f)( mp_size_t<K+15>() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<std::size_t N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||
{
|
||||
assert( i < N );
|
||||
return detail::mp_with_index_impl_<N>::template call<0>( i, std::forward<F>(f) );
|
||||
}
|
||||
|
||||
template<class N, class F> inline BOOST_MP11_CONSTEXPR14 decltype(std::declval<F>()(std::declval<mp_size_t<0>>())) mp_with_index( std::size_t i, F && f )
|
||||
{
|
||||
return mp_with_index<std::size_t{N::value}>( i, std::forward<F>(f) );
|
||||
}
|
||||
|
||||
#undef BOOST_MP11_CONSTEXPR14
|
||||
#undef BOOST_MP11_UNREACHABLE_DEFAULT
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_DETAIL_MP_WITH_INDEX_HPP_INCLUDED
|
222
boost/mp11/function.hpp
Normal file
222
boost/mp11/function.hpp
Normal file
@ -0,0 +1,222 @@
|
||||
#ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||
#define BOOST_MP11_FUNCTION_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_count.hpp>
|
||||
#include <boost/mp11/detail/mp_plus.hpp>
|
||||
#include <boost/mp11/detail/mp_min_element.hpp>
|
||||
#include <boost/mp11/detail/mp_void.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_void<T...>
|
||||
// in detail/mp_void.hpp
|
||||
|
||||
// mp_and<T...>
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_and_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<> struct mp_and_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_and_impl<T>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_and_impl<T1, T...>
|
||||
{
|
||||
using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#else
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class E = void> struct mp_and_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> >
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_all<T...>
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_all = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_false >::value == 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_or<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_or_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<> struct mp_or_impl<>
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<class T> struct mp_or_impl<T>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_or_impl<T1, T...>
|
||||
{
|
||||
using type = mp_eval_if< T1, T1, mp_or, T... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_any<T...>
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 )
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >;
|
||||
|
||||
#else
|
||||
|
||||
template<class... T> using mp_any = mp_bool< mp_count< mp_list<mp_to_bool<T>...>, mp_true >::value != 0 >;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_same<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_same_impl;
|
||||
|
||||
template<> struct mp_same_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class... T> struct mp_same_impl<T1, T...>
|
||||
{
|
||||
using type = mp_bool< mp_count<mp_list<T...>, T1>::value == sizeof...(T) >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type;
|
||||
|
||||
// mp_similar<T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... T> struct mp_similar_impl;
|
||||
|
||||
template<> struct mp_similar_impl<>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_similar_impl<T>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T> struct mp_similar_impl<T, T>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class T2> struct mp_similar_impl<T1, T2>
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T1, class... T2> struct mp_similar_impl<L<T1...>, L<T2...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>>
|
||||
{
|
||||
using type = mp_true;
|
||||
};
|
||||
|
||||
template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...>
|
||||
{
|
||||
using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... T> using mp_similar = typename detail::mp_similar_impl<T...>::type;
|
||||
|
||||
#if BOOST_MP11_GCC
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
// mp_less<T1, T2>
|
||||
template<class T1, class T2> using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>;
|
||||
|
||||
#if BOOST_MP11_GCC
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// mp_min<T...>
|
||||
template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>;
|
||||
|
||||
// mp_max<T...>
|
||||
template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED
|
112
boost/mp11/integer_sequence.hpp
Normal file
112
boost/mp11/integer_sequence.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
#ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
#define BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2017, 2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/version.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__make_integer_seq)
|
||||
# define BOOST_MP11_HAS_MAKE_INTEGER_SEQ
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// integer_sequence
|
||||
template<class T, T... I> struct integer_sequence
|
||||
{
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
template<class T, T N> using make_integer_sequence = __make_integer_seq<integer_sequence, T, N>;
|
||||
|
||||
#else
|
||||
|
||||
// detail::make_integer_sequence_impl
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// iseq_if_c
|
||||
template<bool C, class T, class E> struct iseq_if_c_impl;
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<true, T, E>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, class E> struct iseq_if_c_impl<false, T, E>
|
||||
{
|
||||
using type = E;
|
||||
};
|
||||
|
||||
template<bool C, class T, class E> using iseq_if_c = typename iseq_if_c_impl<C, T, E>::type;
|
||||
|
||||
// iseq_identity
|
||||
template<class T> struct iseq_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class S1, class S2> struct append_integer_sequence;
|
||||
|
||||
template<class T, T... I, T... J> struct append_integer_sequence<integer_sequence<T, I...>, integer_sequence<T, J...>>
|
||||
{
|
||||
using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl;
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl_
|
||||
{
|
||||
private:
|
||||
|
||||
static_assert( N >= 0, "make_integer_sequence<T, N>: N must not be negative" );
|
||||
|
||||
static T const M = N / 2;
|
||||
static T const R = N % 2;
|
||||
|
||||
using S1 = typename make_integer_sequence_impl<T, M>::type;
|
||||
using S2 = typename append_integer_sequence<S1, S1>::type;
|
||||
using S3 = typename make_integer_sequence_impl<T, R>::type;
|
||||
using S4 = typename append_integer_sequence<S2, S3>::type;
|
||||
|
||||
public:
|
||||
|
||||
using type = S4;
|
||||
};
|
||||
|
||||
template<class T, T N> struct make_integer_sequence_impl: iseq_if_c<N == 0, iseq_identity<integer_sequence<T>>, iseq_if_c<N == 1, iseq_identity<integer_sequence<T, 0>>, make_integer_sequence_impl_<T, N> > >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// make_integer_sequence
|
||||
template<class T, T N> using make_integer_sequence = typename detail::make_integer_sequence_impl<T, N>::type;
|
||||
|
||||
#endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ)
|
||||
|
||||
// index_sequence
|
||||
template<std::size_t... I> using index_sequence = integer_sequence<std::size_t, I...>;
|
||||
|
||||
// make_index_sequence
|
||||
template<std::size_t N> using make_index_sequence = make_integer_sequence<std::size_t, N>;
|
||||
|
||||
// index_sequence_for
|
||||
template<class... T> using index_sequence_for = make_integer_sequence<std::size_t, sizeof...(T)>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_INTEGER_SEQUENCE_HPP_INCLUDED
|
42
boost/mp11/integral.hpp
Normal file
42
boost/mp11/integral.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
||||
#define BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/version.hpp>
|
||||
#include <boost/mp11/detail/mp_value.hpp>
|
||||
#include <type_traits>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_bool
|
||||
template<bool B> using mp_bool = std::integral_constant<bool, B>;
|
||||
|
||||
using mp_true = mp_bool<true>;
|
||||
using mp_false = mp_bool<false>;
|
||||
|
||||
// mp_to_bool
|
||||
template<class T> using mp_to_bool = mp_bool<static_cast<bool>( T::value )>;
|
||||
|
||||
// mp_not<T>
|
||||
template<class T> using mp_not = mp_bool< !T::value >;
|
||||
|
||||
// mp_int
|
||||
template<int I> using mp_int = std::integral_constant<int, I>;
|
||||
|
||||
// mp_size_t
|
||||
template<std::size_t N> using mp_size_t = std::integral_constant<std::size_t, N>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_INTEGRAL_HPP_INCLUDED
|
472
boost/mp11/list.hpp
Normal file
472
boost/mp11/list.hpp
Normal file
@ -0,0 +1,472 @@
|
||||
#ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
||||
#define BOOST_MP11_LIST_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2023 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_list_v.hpp>
|
||||
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||
#include <boost/mp11/detail/mp_is_value_list.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_list<T...>
|
||||
// in detail/mp_list.hpp
|
||||
|
||||
// mp_list_c<T, I...>
|
||||
template<class T, T... I> using mp_list_c = mp_list<std::integral_constant<T, I>...>;
|
||||
|
||||
// mp_list_v<A...>
|
||||
// in detail/mp_list_v.hpp
|
||||
|
||||
// mp_is_list<L>
|
||||
// in detail/mp_is_list.hpp
|
||||
|
||||
// mp_is_value_list<L>
|
||||
// in detail/mp_is_value_list.hpp
|
||||
|
||||
// mp_size<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_size_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_size is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_size_impl<L<T...>>
|
||||
{
|
||||
using type = mp_size_t<sizeof...(T)>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A> struct mp_size_impl<L<A...>>
|
||||
{
|
||||
using type = mp_size_t<sizeof...(A)>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_size = typename detail::mp_size_impl<L>::type;
|
||||
|
||||
// mp_empty<L>
|
||||
template<class L> using mp_empty = mp_bool< mp_size<L>::value == 0 >;
|
||||
|
||||
// mp_assign<L1, L2>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L1, class L2> struct mp_assign_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the arguments to mp_assign aren't lists
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T, template<class...> class L2, class... U> struct mp_assign_impl<L1<T...>, L2<U...>>
|
||||
{
|
||||
using type = L1<U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L1, auto... A, template<class...> class L2, class... U> struct mp_assign_impl<L1<A...>, L2<U...>>
|
||||
{
|
||||
using type = L1<U::value...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<T...>, L2<B...>>
|
||||
{
|
||||
using type = L1<mp_value<B>...>;
|
||||
};
|
||||
|
||||
template<template<auto...> class L1, auto... A, template<auto...> class L2, auto... B> struct mp_assign_impl<L1<A...>, L2<B...>>
|
||||
{
|
||||
using type = L1<B...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L1, L2>::type;
|
||||
|
||||
// mp_clear<L>
|
||||
template<class L> using mp_clear = mp_assign<L, mp_list<>>;
|
||||
|
||||
// mp_front<L>
|
||||
// in detail/mp_front.hpp
|
||||
|
||||
// mp_pop_front<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_pop_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_pop_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class... T> struct mp_pop_front_impl<L<T1, T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A> struct mp_pop_front_impl<L<A1, A...>>
|
||||
{
|
||||
using type = L<A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_pop_front = typename detail::mp_pop_front_impl<L>::type;
|
||||
|
||||
// mp_first<L>
|
||||
template<class L> using mp_first = mp_front<L>;
|
||||
|
||||
// mp_rest<L>
|
||||
template<class L> using mp_rest = mp_pop_front<L>;
|
||||
|
||||
// mp_second<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class... T> struct mp_second_impl<L<T1, T2, T...>>
|
||||
{
|
||||
using type = T2;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A> struct mp_second_impl<L<A1, A2, A...>>
|
||||
{
|
||||
using type = mp_value<A2>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_second = typename detail::mp_second_impl<L>::type;
|
||||
|
||||
// mp_third<L>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L> struct mp_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the argument to mp_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class T1, class T2, class T3, class... T> struct mp_third_impl<L<T1, T2, T3, T...>>
|
||||
{
|
||||
using type = T3;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A> struct mp_third_impl<L<A1, A2, A3, A...>>
|
||||
{
|
||||
using type = mp_value<A3>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L> using mp_third = typename detail::mp_third_impl<L>::type;
|
||||
|
||||
// mp_push_front<L, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class... T> struct mp_push_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_push_front is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class... T> struct mp_push_front_impl<L<U...>, T...>
|
||||
{
|
||||
using type = L<T..., U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, class... T> struct mp_push_front_impl<L<A...>, T...>
|
||||
{
|
||||
using type = L<T::value..., A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... T> using mp_push_front = typename detail::mp_push_front_impl<L, T...>::type;
|
||||
|
||||
// mp_push_back<L, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class... T> struct mp_push_back_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_push_back is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class... T> struct mp_push_back_impl<L<U...>, T...>
|
||||
{
|
||||
using type = L<U..., T...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto... A, class... T> struct mp_push_back_impl<L<A...>, T...>
|
||||
{
|
||||
using type = L<A..., T::value...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... T> using mp_push_back = typename detail::mp_push_back_impl<L, T...>::type;
|
||||
|
||||
// mp_rename<L, B>
|
||||
// mp_apply<F, L>
|
||||
// mp_apply_q<Q, L>
|
||||
// in detail/mp_rename.hpp
|
||||
|
||||
// mp_rename_v<L, B>
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<auto...> class B> struct mp_rename_v_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_rename_v is not a list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, template<auto...> class B> struct mp_rename_v_impl<L<T...>, B>
|
||||
{
|
||||
using type = B<T::value...>;
|
||||
};
|
||||
|
||||
template<template<auto...> class L, auto... A, template<auto...> class B> struct mp_rename_v_impl<L<A...>, B>
|
||||
{
|
||||
using type = B<A...>;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<auto...> class B> using mp_rename_v = typename detail::mp_rename_v_impl<L, B>::type;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_replace_front<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class... U, class T> struct mp_replace_front_impl<L<U1, U...>, T>
|
||||
{
|
||||
using type = L<T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A, class T> struct mp_replace_front_impl<L<A1, A...>, T>
|
||||
{
|
||||
using type = L<T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_front = typename detail::mp_replace_front_impl<L, T>::type;
|
||||
|
||||
// mp_replace_first<L, T>
|
||||
template<class L, class T> using mp_replace_first = typename detail::mp_replace_front_impl<L, T>::type;
|
||||
|
||||
// mp_replace_second<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl<L<U1, U2, U...>, T>
|
||||
{
|
||||
using type = L<U1, T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A, class T> struct mp_replace_second_impl<L<A1, A2, A...>, T>
|
||||
{
|
||||
using type = L<A1, T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_second = typename detail::mp_replace_second_impl<L, T>::type;
|
||||
|
||||
// mp_replace_third<L, T>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class T> struct mp_replace_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_replace_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl<L<U1, U2, U3, U...>, T>
|
||||
{
|
||||
using type = L<U1, U2, T, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, class T> struct mp_replace_third_impl<L<A1, A2, A3, A...>, T>
|
||||
{
|
||||
using type = L<A1, A2, T::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class T> using mp_replace_third = typename detail::mp_replace_third_impl<L, T>::type;
|
||||
|
||||
// mp_transform_front<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_front_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_front
|
||||
// is either not a list, or is an empty list
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class... U, template<class...> class F> struct mp_transform_front_impl<L<U1, U...>, F>
|
||||
{
|
||||
using type = L<F<U1>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto... A, template<class...> class F> struct mp_transform_front_impl<L<A1, A...>, F>
|
||||
{
|
||||
using type = L<F<mp_value<A1>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_front = typename detail::mp_transform_front_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_front_q = mp_transform_front<L, Q::template fn>;
|
||||
|
||||
// mp_transform_first<L, F>
|
||||
template<class L, template<class...> class F> using mp_transform_first = typename detail::mp_transform_front_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_first_q = mp_transform_first<L, Q::template fn>;
|
||||
|
||||
// mp_transform_second<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_second_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_second
|
||||
// is either not a list, or has fewer than two elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class... U, template<class...> class F> struct mp_transform_second_impl<L<U1, U2, U...>, F>
|
||||
{
|
||||
using type = L<U1, F<U2>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto... A, template<class...> class F> struct mp_transform_second_impl<L<A1, A2, A...>, F>
|
||||
{
|
||||
using type = L<A1, F<mp_value<A2>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_second = typename detail::mp_transform_second_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_second_q = mp_transform_second<L, Q::template fn>;
|
||||
|
||||
// mp_transform_third<L, F>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, template<class...> class F> struct mp_transform_third_impl
|
||||
{
|
||||
// An error "no type named 'type'" here means that the first argument to mp_transform_third
|
||||
// is either not a list, or has fewer than three elements
|
||||
};
|
||||
|
||||
template<template<class...> class L, class U1, class U2, class U3, class... U, template<class...> class F> struct mp_transform_third_impl<L<U1, U2, U3, U...>, F>
|
||||
{
|
||||
using type = L<U1, U2, F<U3>, U...>;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP11_HAS_TEMPLATE_AUTO)
|
||||
|
||||
template<template<auto...> class L, auto A1, auto A2, auto A3, auto... A, template<class...> class F> struct mp_transform_third_impl<L<A1, A2, A3, A...>, F>
|
||||
{
|
||||
using type = L<A1, A2, F<mp_value<A3>>::value, A...>;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, template<class...> class F> using mp_transform_third = typename detail::mp_transform_third_impl<L, F>::type;
|
||||
template<class L, class Q> using mp_transform_third_q = mp_transform_third<L, Q::template fn>;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED
|
188
boost/mp11/set.hpp
Normal file
188
boost/mp11/set.hpp
Normal file
@ -0,0 +1,188 @@
|
||||
#ifndef BOOST_MP11_SET_HPP_INCLUDED
|
||||
#define BOOST_MP11_SET_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015, 2019 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/utility.hpp>
|
||||
#include <boost/mp11/function.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_append.hpp>
|
||||
#include <boost/mp11/detail/mp_copy_if.hpp>
|
||||
#include <boost/mp11/detail/mp_remove_if.hpp>
|
||||
#include <boost/mp11/detail/mp_is_list.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_set_contains<S, V>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class V> struct mp_set_contains_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T, class V> struct mp_set_contains_impl<L<T...>, V>
|
||||
{
|
||||
using type = mp_to_bool<std::is_base_of<mp_identity<V>, mp_inherit<mp_identity<T>...> > >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class V> using mp_set_contains = typename detail::mp_set_contains_impl<S, V>::type;
|
||||
|
||||
// mp_set_push_back<S, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class... T> struct mp_set_push_back_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U> struct mp_set_push_back_impl<L<U...>>
|
||||
{
|
||||
using type = L<U...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_back_impl<L<U...>, T1, T...>
|
||||
{
|
||||
using S = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<U..., T1>>;
|
||||
using type = typename mp_set_push_back_impl<S, T...>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class... T> using mp_set_push_back = typename detail::mp_set_push_back_impl<S, T...>::type;
|
||||
|
||||
// mp_set_push_front<S, T...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S, class... T> struct mp_set_push_front_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U> struct mp_set_push_front_impl<L<U...>>
|
||||
{
|
||||
using type = L<U...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1> struct mp_set_push_front_impl<L<U...>, T1>
|
||||
{
|
||||
using type = mp_if<mp_set_contains<L<U...>, T1>, L<U...>, L<T1, U...>>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... U, class T1, class... T> struct mp_set_push_front_impl<L<U...>, T1, T...>
|
||||
{
|
||||
using S = typename mp_set_push_front_impl<L<U...>, T...>::type;
|
||||
using type = typename mp_set_push_front_impl<S, T1>::type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S, class... T> using mp_set_push_front = typename detail::mp_set_push_front_impl<S, T...>::type;
|
||||
|
||||
// mp_is_set<S>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class S> struct mp_is_set_impl
|
||||
{
|
||||
using type = mp_false;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_is_set_impl<L<T...>>
|
||||
{
|
||||
using type = mp_to_bool<std::is_same<mp_list<T...>, mp_set_push_back<mp_list<>, T...> > >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class S> using mp_is_set = typename detail::mp_is_set_impl<S>::type;
|
||||
|
||||
// mp_set_union<L...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... L> struct mp_set_union_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_set_union_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<template<class...> class L, class... T> struct mp_set_union_impl<L<T...>>
|
||||
{
|
||||
using type = L<T...>;
|
||||
};
|
||||
|
||||
template<template<class...> class L1, class... T1, template<class...> class L2, class... T2> struct mp_set_union_impl<L1<T1...>, L2<T2...>>
|
||||
{
|
||||
using type = mp_set_push_back<L1<T1...>, T2...>;
|
||||
};
|
||||
|
||||
template<class L1, class... L> using mp_set_union_ = typename mp_set_union_impl<L1, mp_append<mp_list<>, L...>>::type;
|
||||
|
||||
template<class L1, class L2, class L3, class... L> struct mp_set_union_impl<L1, L2, L3, L...>: mp_defer<mp_set_union_, L1, L2, L3, L...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... L> using mp_set_union = typename detail::mp_set_union_impl<L...>::type;
|
||||
|
||||
// mp_set_intersection<S...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... S> struct in_all_sets
|
||||
{
|
||||
template<class T> using fn = mp_all< mp_set_contains<S, T>... >;
|
||||
};
|
||||
|
||||
template<class L, class... S> using mp_set_intersection_ = mp_if< mp_all<mp_is_list<S>...>, mp_copy_if_q<L, detail::in_all_sets<S...>> >;
|
||||
|
||||
template<class... S> struct mp_set_intersection_impl
|
||||
{
|
||||
};
|
||||
|
||||
template<> struct mp_set_intersection_impl<>
|
||||
{
|
||||
using type = mp_list<>;
|
||||
};
|
||||
|
||||
template<class L, class... S> struct mp_set_intersection_impl<L, S...>: mp_defer<mp_set_intersection_, L, S...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class... S> using mp_set_intersection = typename detail::mp_set_intersection_impl<S...>::type;
|
||||
|
||||
// mp_set_difference<L, S...>
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class... S> struct in_any_set
|
||||
{
|
||||
template<class T> using fn = mp_any< mp_set_contains<S, T>... >;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class L, class... S> using mp_set_difference = mp_if< mp_all<mp_is_list<S>...>, mp_remove_if_q<L, detail::in_any_set<S...>> >;
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_SET_HPP_INCLUDED
|
169
boost/mp11/utility.hpp
Normal file
169
boost/mp11/utility.hpp
Normal file
@ -0,0 +1,169 @@
|
||||
#ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
#define BOOST_MP11_UTILITY_HPP_INCLUDED
|
||||
|
||||
// Copyright 2015-2020 Peter Dimov.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/mp11/integral.hpp>
|
||||
#include <boost/mp11/detail/mp_list.hpp>
|
||||
#include <boost/mp11/detail/mp_fold.hpp>
|
||||
#include <boost/mp11/detail/mp_front.hpp>
|
||||
#include <boost/mp11/detail/mp_rename.hpp>
|
||||
#include <boost/mp11/detail/mp_defer.hpp>
|
||||
#include <boost/mp11/detail/config.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace mp11
|
||||
{
|
||||
|
||||
// mp_identity
|
||||
template<class T> struct mp_identity
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
// mp_identity_t
|
||||
template<class T> using mp_identity_t = typename mp_identity<T>::type;
|
||||
|
||||
// mp_inherit
|
||||
template<class... T> struct mp_inherit: T... {};
|
||||
|
||||
// mp_if, mp_if_c
|
||||
// mp_valid
|
||||
// mp_defer
|
||||
// moved to detail/mp_defer.hpp
|
||||
|
||||
// mp_eval_if, mp_eval_if_c
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<bool C, class T, template<class...> class F, class... U> struct mp_eval_if_c_impl;
|
||||
|
||||
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<true, T, F, U...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<false, T, F, U...>: mp_defer<F, U...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl<C, T, F, U...>::type;
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, F, U...>::type;
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_q = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, Q::template fn, U...>::type;
|
||||
|
||||
// mp_eval_if_not
|
||||
template<class C, class T, template<class...> class F, class... U> using mp_eval_if_not = mp_eval_if<mp_not<C>, T, F, U...>;
|
||||
template<class C, class T, class Q, class... U> using mp_eval_if_not_q = mp_eval_if<mp_not<C>, T, Q::template fn, U...>;
|
||||
|
||||
// mp_eval_or
|
||||
template<class T, template<class...> class F, class... U> using mp_eval_or = mp_eval_if_not<mp_valid<F, U...>, T, F, U...>;
|
||||
template<class T, class Q, class... U> using mp_eval_or_q = mp_eval_or<T, Q::template fn, U...>;
|
||||
|
||||
// mp_valid_and_true
|
||||
template<template<class...> class F, class... T> using mp_valid_and_true = mp_eval_or<mp_false, F, T...>;
|
||||
template<class Q, class... T> using mp_valid_and_true_q = mp_valid_and_true<Q::template fn, T...>;
|
||||
|
||||
// mp_cond
|
||||
|
||||
// so elegant; so doesn't work
|
||||
// template<class C, class T, class... E> using mp_cond = mp_eval_if<C, T, mp_cond, E...>;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class C, class T, class... E> struct mp_cond_impl;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class C, class T, class... E> using mp_cond = typename detail::mp_cond_impl<C, T, E...>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class C, class T, class... E> using mp_cond_ = mp_eval_if<C, T, mp_cond, E...>;
|
||||
|
||||
template<class C, class T, class... E> struct mp_cond_impl: mp_defer<mp_cond_, C, T, E...>
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// mp_quote
|
||||
template<template<class...> class F> struct mp_quote
|
||||
{
|
||||
// the indirection through mp_defer works around the language inability
|
||||
// to expand T... into a fixed parameter list of an alias template
|
||||
|
||||
template<class... T> using fn = typename mp_defer<F, T...>::type;
|
||||
};
|
||||
|
||||
// mp_quote_trait
|
||||
template<template<class...> class F> struct mp_quote_trait
|
||||
{
|
||||
template<class... T> using fn = typename F<T...>::type;
|
||||
};
|
||||
|
||||
// mp_invoke_q
|
||||
#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class Q, class... T> struct mp_invoke_q_impl: mp_defer<Q::template fn, T...> {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename detail::mp_invoke_q_impl<Q, T...>::type;
|
||||
|
||||
#elif BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 50000 )
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename mp_defer<Q::template fn, T...>::type;
|
||||
|
||||
#else
|
||||
|
||||
template<class Q, class... T> using mp_invoke_q = typename Q::template fn<T...>;
|
||||
|
||||
#endif
|
||||
|
||||
// mp_not_fn<P>
|
||||
template<template<class...> class P> struct mp_not_fn
|
||||
{
|
||||
template<class... T> using fn = mp_not< mp_invoke_q<mp_quote<P>, T...> >;
|
||||
};
|
||||
|
||||
template<class Q> using mp_not_fn_q = mp_not_fn<Q::template fn>;
|
||||
|
||||
// mp_compose
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<class L, class Q> using mp_compose_helper = mp_list< mp_apply_q<Q, L> >;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
#if !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 )
|
||||
|
||||
template<template<class...> class... F> struct mp_compose
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<mp_quote<F>...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template<class... Q> struct mp_compose_q
|
||||
{
|
||||
template<class... T> using fn = mp_front< mp_fold<mp_list<Q...>, mp_list<T...>, detail::mp_compose_helper> >;
|
||||
};
|
||||
|
||||
} // namespace mp11
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
|
16
boost/mp11/version.hpp
Normal file
16
boost/mp11/version.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
#define BOOST_MP11_VERSION_HPP_INCLUDED
|
||||
|
||||
// Copyright 2019 Peter Dimov
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
//
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
// Same format as BOOST_VERSION:
|
||||
// major * 100000 + minor * 100 + patch
|
||||
|
||||
#define BOOST_MP11_VERSION 108400
|
||||
|
||||
#endif // #ifndef BOOST_MP11_VERSION_HPP_INCLUDED
|
40
boost/mpl/O1_size.hpp
Normal file
40
boost/mpl/O1_size.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
#ifndef BOOST_MPL_O1_SIZE_HPP_INCLUDED
|
||||
#define BOOST_MPL_O1_SIZE_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/O1_size_fwd.hpp>
|
||||
#include <boost/mpl/sequence_tag.hpp>
|
||||
#include <boost/mpl/aux_/O1_size_impl.hpp>
|
||||
#include <boost/mpl/aux_/na_spec.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
// returns sequence size if it's an O(1) operation; otherwise returns -1
|
||||
template<
|
||||
typename BOOST_MPL_AUX_NA_PARAM(Sequence)
|
||||
>
|
||||
struct O1_size
|
||||
: O1_size_impl< typename sequence_tag<Sequence>::type >
|
||||
::template apply< Sequence >
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1, O1_size, (Sequence))
|
||||
};
|
||||
|
||||
BOOST_MPL_AUX_NA_SPEC(1, O1_size)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_O1_SIZE_HPP_INCLUDED
|
24
boost/mpl/O1_size_fwd.hpp
Normal file
24
boost/mpl/O1_size_fwd.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
|
||||
#define BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template< typename Tag > struct O1_size_impl;
|
||||
template< typename Sequence > struct O1_size;
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
|
76
boost/mpl/advance.hpp
Normal file
76
boost/mpl/advance.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
|
||||
#ifndef BOOST_MPL_ADVANCE_HPP_INCLUDED
|
||||
#define BOOST_MPL_ADVANCE_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/advance_fwd.hpp>
|
||||
#include <boost/mpl/less.hpp>
|
||||
#include <boost/mpl/negate.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/tag.hpp>
|
||||
#include <boost/mpl/apply_wrap.hpp>
|
||||
#include <boost/mpl/aux_/advance_forward.hpp>
|
||||
#include <boost/mpl/aux_/advance_backward.hpp>
|
||||
#include <boost/mpl/aux_/value_wknd.hpp>
|
||||
#include <boost/mpl/aux_/na_spec.hpp>
|
||||
#include <boost/mpl/aux_/nttp_decl.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
// default implementation for forward/bidirectional iterators
|
||||
template< typename Tag >
|
||||
struct advance_impl
|
||||
{
|
||||
template< typename Iterator, typename N > struct apply
|
||||
{
|
||||
typedef typename less< N,long_<0> >::type backward_;
|
||||
typedef typename if_< backward_, negate<N>, N >::type offset_;
|
||||
|
||||
typedef typename if_<
|
||||
backward_
|
||||
, aux::advance_backward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value >
|
||||
, aux::advance_forward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value >
|
||||
>::type f_;
|
||||
|
||||
typedef typename apply_wrap1<f_,Iterator>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<
|
||||
typename BOOST_MPL_AUX_NA_PARAM(Iterator)
|
||||
, typename BOOST_MPL_AUX_NA_PARAM(N)
|
||||
>
|
||||
struct advance
|
||||
: advance_impl< typename tag<Iterator>::type >
|
||||
::template apply<Iterator,N>
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
typename Iterator
|
||||
, BOOST_MPL_AUX_NTTP_DECL(long, N)
|
||||
>
|
||||
struct advance_c
|
||||
: advance_impl< typename tag<Iterator>::type >
|
||||
::template apply<Iterator,long_<N> >
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_MPL_AUX_NA_SPEC(2, advance)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_ADVANCE_HPP_INCLUDED
|
28
boost/mpl/advance_fwd.hpp
Normal file
28
boost/mpl/advance_fwd.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
#ifndef BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
|
||||
#define BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/aux_/common_name_wknd.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
BOOST_MPL_AUX_COMMON_NAME_WKND(advance)
|
||||
|
||||
template< typename Tag > struct advance_impl;
|
||||
template< typename Iterator, typename N > struct advance;
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
|
52
boost/mpl/at.hpp
Normal file
52
boost/mpl/at.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
#ifndef BOOST_MPL_AT_HPP_INCLUDED
|
||||
#define BOOST_MPL_AT_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/at_fwd.hpp>
|
||||
#include <boost/mpl/aux_/at_impl.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/mpl/sequence_tag.hpp>
|
||||
#include <boost/mpl/aux_/na_spec.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
#include <boost/mpl/aux_/nttp_decl.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template<
|
||||
typename BOOST_MPL_AUX_NA_PARAM(Sequence)
|
||||
, typename BOOST_MPL_AUX_NA_PARAM(N)
|
||||
>
|
||||
struct at
|
||||
: at_impl< typename sequence_tag<Sequence>::type >
|
||||
::template apply< Sequence,N >
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(2,at,(Sequence,N))
|
||||
};
|
||||
|
||||
template<
|
||||
typename Sequence
|
||||
, BOOST_MPL_AUX_NTTP_DECL(long, N)
|
||||
>
|
||||
struct at_c
|
||||
: at_impl< typename sequence_tag<Sequence>::type >
|
||||
::template apply< Sequence,mpl::long_<N> >
|
||||
{
|
||||
};
|
||||
|
||||
BOOST_MPL_AUX_NA_SPEC(2, at)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AT_HPP_INCLUDED
|
24
boost/mpl/at_fwd.hpp
Normal file
24
boost/mpl/at_fwd.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef BOOST_MPL_AT_FWD_HPP_INCLUDED
|
||||
#define BOOST_MPL_AT_FWD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
template< typename Tag > struct at_impl;
|
||||
template< typename Sequence, typename N > struct at;
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AT_FWD_HPP_INCLUDED
|
87
boost/mpl/aux_/O1_size_impl.hpp
Normal file
87
boost/mpl/aux_/O1_size_impl.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
#ifndef BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/O1_size_fwd.hpp>
|
||||
#include <boost/mpl/long.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/aux_/has_size.hpp>
|
||||
#include <boost/mpl/aux_/config/forwarding.hpp>
|
||||
#include <boost/mpl/aux_/config/static_constant.hpp>
|
||||
#include <boost/mpl/aux_/config/msvc.hpp>
|
||||
#include <boost/mpl/aux_/config/workaround.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
// default implementation - returns 'Sequence::size' if sequence has a 'size'
|
||||
// member, and -1 otherwise; conrete sequences might override it by
|
||||
// specializing either the 'O1_size_impl' or the primary 'O1_size' template
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
|
||||
&& !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
|
||||
|
||||
namespace aux {
|
||||
template< typename Sequence > struct O1_size_impl
|
||||
: Sequence::size
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template< typename Tag >
|
||||
struct O1_size_impl
|
||||
{
|
||||
template< typename Sequence > struct apply
|
||||
#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
|
||||
: if_<
|
||||
aux::has_size<Sequence>
|
||||
, aux::O1_size_impl<Sequence>
|
||||
, long_<-1>
|
||||
>::type
|
||||
{
|
||||
#else
|
||||
{
|
||||
typedef typename if_<
|
||||
aux::has_size<Sequence>
|
||||
, aux::O1_size_impl<Sequence>
|
||||
, long_<-1>
|
||||
>::type type;
|
||||
|
||||
BOOST_STATIC_CONSTANT(long, value =
|
||||
(if_<
|
||||
aux::has_size<Sequence>
|
||||
, aux::O1_size_impl<Sequence>
|
||||
, long_<-1>
|
||||
>::type::value)
|
||||
);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
# else // BOOST_MSVC
|
||||
|
||||
template< typename Tag >
|
||||
struct O1_size_impl
|
||||
{
|
||||
template< typename Sequence > struct apply
|
||||
: long_<-1>
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
|
128
boost/mpl/aux_/advance_backward.hpp
Normal file
128
boost/mpl/aux_/advance_backward.hpp
Normal file
@ -0,0 +1,128 @@
|
||||
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
///// header body
|
||||
|
||||
#ifndef BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
# include <boost/mpl/prior.hpp>
|
||||
# include <boost/mpl/apply_wrap.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
|
||||
# define BOOST_MPL_PREPROCESSED_HEADER advance_backward.hpp
|
||||
# include <boost/mpl/aux_/include_preprocessed.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# include <boost/mpl/limits/unrolling.hpp>
|
||||
# include <boost/mpl/aux_/nttp_decl.hpp>
|
||||
# include <boost/mpl/aux_/config/eti.hpp>
|
||||
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/inc.hpp>
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
|
||||
// forward declaration
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_backward;
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/advance_backward.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
|
||||
struct advance_backward
|
||||
{
|
||||
template< typename Iterator > struct apply
|
||||
{
|
||||
typedef typename apply_wrap1<
|
||||
advance_backward<BOOST_MPL_LIMIT_UNROLLING>
|
||||
, Iterator
|
||||
>::type chunk_result_;
|
||||
|
||||
typedef typename apply_wrap1<
|
||||
advance_backward<(
|
||||
(N - BOOST_MPL_LIMIT_UNROLLING) < 0
|
||||
? 0
|
||||
: N - BOOST_MPL_LIMIT_UNROLLING
|
||||
)>
|
||||
, chunk_result_
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
#endif // BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
|
||||
|
||||
///// iteration, depth == 1
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#define i_ BOOST_PP_FRAME_ITERATION(1)
|
||||
|
||||
template<>
|
||||
struct advance_backward< BOOST_PP_FRAME_ITERATION(1) >
|
||||
{
|
||||
template< typename Iterator > struct apply
|
||||
{
|
||||
typedef Iterator iter0;
|
||||
|
||||
#if i_ > 0
|
||||
# define BOOST_PP_ITERATION_PARAMS_2 \
|
||||
(3,(1, BOOST_PP_FRAME_ITERATION(1), <boost/mpl/aux_/advance_backward.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
#endif
|
||||
|
||||
typedef BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(1)) type;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
|
||||
/// ETI workaround
|
||||
template<> struct apply<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#undef i_
|
||||
|
||||
///// iteration, depth == 2
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 2
|
||||
|
||||
# define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2)))
|
||||
# define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2))
|
||||
|
||||
typedef typename prior<AUX778076_ITER_0>::type AUX778076_ITER_1;
|
||||
|
||||
# undef AUX778076_ITER_1
|
||||
# undef AUX778076_ITER_0
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // BOOST_PP_IS_ITERATING
|
127
boost/mpl/aux_/advance_forward.hpp
Normal file
127
boost/mpl/aux_/advance_forward.hpp
Normal file
@ -0,0 +1,127 @@
|
||||
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
///// header body
|
||||
|
||||
#ifndef BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
# include <boost/mpl/next.hpp>
|
||||
# include <boost/mpl/apply_wrap.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
|
||||
# define BOOST_MPL_PREPROCESSED_HEADER advance_forward.hpp
|
||||
# include <boost/mpl/aux_/include_preprocessed.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# include <boost/mpl/limits/unrolling.hpp>
|
||||
# include <boost/mpl/aux_/nttp_decl.hpp>
|
||||
# include <boost/mpl/aux_/config/eti.hpp>
|
||||
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
# include <boost/preprocessor/inc.hpp>
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
|
||||
// forward declaration
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_forward;
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/advance_forward.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
|
||||
struct advance_forward
|
||||
{
|
||||
template< typename Iterator > struct apply
|
||||
{
|
||||
typedef typename apply_wrap1<
|
||||
advance_forward<BOOST_MPL_LIMIT_UNROLLING>
|
||||
, Iterator
|
||||
>::type chunk_result_;
|
||||
|
||||
typedef typename apply_wrap1<
|
||||
advance_forward<(
|
||||
(N - BOOST_MPL_LIMIT_UNROLLING) < 0
|
||||
? 0
|
||||
: N - BOOST_MPL_LIMIT_UNROLLING
|
||||
)>
|
||||
, chunk_result_
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
#endif // BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
|
||||
|
||||
///// iteration, depth == 1
|
||||
|
||||
// For gcc 4.4 compatability, we must include the
|
||||
// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
|
||||
#else // BOOST_PP_IS_ITERATING
|
||||
#if BOOST_PP_ITERATION_DEPTH() == 1
|
||||
#define i_ BOOST_PP_FRAME_ITERATION(1)
|
||||
|
||||
template<>
|
||||
struct advance_forward< BOOST_PP_FRAME_ITERATION(1) >
|
||||
{
|
||||
template< typename Iterator > struct apply
|
||||
{
|
||||
typedef Iterator iter0;
|
||||
|
||||
#if i_ > 0
|
||||
# define BOOST_PP_ITERATION_PARAMS_2 \
|
||||
(3,(1, i_, <boost/mpl/aux_/advance_forward.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
#endif
|
||||
typedef BOOST_PP_CAT(iter,i_) type;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
|
||||
/// ETI workaround
|
||||
template<> struct apply<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#undef i_
|
||||
|
||||
///// iteration, depth == 2
|
||||
|
||||
#elif BOOST_PP_ITERATION_DEPTH() == 2
|
||||
|
||||
# define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2)))
|
||||
# define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2))
|
||||
|
||||
typedef typename next<AUX778076_ITER_0>::type AUX778076_ITER_1;
|
||||
|
||||
# undef AUX778076_ITER_1
|
||||
# undef AUX778076_ITER_0
|
||||
|
||||
#endif // BOOST_PP_ITERATION_DEPTH()
|
||||
#endif // BOOST_PP_IS_ITERATING
|
45
boost/mpl/aux_/at_impl.hpp
Normal file
45
boost/mpl/aux_/at_impl.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_AT_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_AT_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/begin_end.hpp>
|
||||
#include <boost/mpl/advance.hpp>
|
||||
#include <boost/mpl/deref.hpp>
|
||||
#include <boost/mpl/aux_/traits_lambda_spec.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
// default implementation; conrete sequences might override it by
|
||||
// specializing either the 'at_impl' or the primary 'at' template
|
||||
|
||||
template< typename Tag >
|
||||
struct at_impl
|
||||
{
|
||||
template< typename Sequence, typename N > struct apply
|
||||
{
|
||||
typedef typename advance<
|
||||
typename begin<Sequence>::type
|
||||
, N
|
||||
>::type iter_;
|
||||
|
||||
typedef typename deref<iter_>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, at_impl)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_AT_IMPL_HPP_INCLUDED
|
101
boost/mpl/aux_/begin_end_impl.hpp
Normal file
101
boost/mpl/aux_/begin_end_impl.hpp
Normal file
@ -0,0 +1,101 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/begin_end_fwd.hpp>
|
||||
#include <boost/mpl/sequence_tag_fwd.hpp>
|
||||
#include <boost/mpl/void.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/aux_/has_begin.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/aux_/traits_lambda_spec.hpp>
|
||||
#include <boost/mpl/aux_/config/eti.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
|
||||
namespace aux {
|
||||
|
||||
template< typename Sequence >
|
||||
struct begin_type
|
||||
{
|
||||
typedef typename Sequence::begin type;
|
||||
};
|
||||
template< typename Sequence >
|
||||
struct end_type
|
||||
{
|
||||
typedef typename Sequence::end type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// default implementation; conrete sequences might override it by
|
||||
// specializing either the 'begin_impl/end_impl' or the primary
|
||||
// 'begin/end' templates
|
||||
|
||||
template< typename Tag >
|
||||
struct begin_impl
|
||||
{
|
||||
template< typename Sequence > struct apply
|
||||
{
|
||||
typedef typename eval_if<aux::has_begin<Sequence, true_>,
|
||||
aux::begin_type<Sequence>, void_>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template< typename Tag >
|
||||
struct end_impl
|
||||
{
|
||||
template< typename Sequence > struct apply
|
||||
{
|
||||
typedef typename eval_if<aux::has_begin<Sequence, true_>,
|
||||
aux::end_type<Sequence>, void_>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
// specialize 'begin_trait/end_trait' for two pre-defined tags
|
||||
|
||||
# define AUX778076_IMPL_SPEC(name, tag, result) \
|
||||
template<> \
|
||||
struct name##_impl<tag> \
|
||||
{ \
|
||||
template< typename Sequence > struct apply \
|
||||
{ \
|
||||
typedef result type; \
|
||||
}; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
// a sequence with nested 'begin/end' typedefs; just query them
|
||||
AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin)
|
||||
AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end)
|
||||
|
||||
// if a type 'T' does not contain 'begin/end' or 'tag' members
|
||||
// and doesn't specialize either 'begin/end' or 'begin_impl/end_impl'
|
||||
// templates, then we end up here
|
||||
AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_)
|
||||
AUX778076_IMPL_SPEC(end, non_sequence_tag, void_)
|
||||
AUX778076_IMPL_SPEC(begin, na, void_)
|
||||
AUX778076_IMPL_SPEC(end, na, void_)
|
||||
|
||||
# undef AUX778076_IMPL_SPEC
|
||||
|
||||
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl)
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
|
35
boost/mpl/aux_/clear_impl.hpp
Normal file
35
boost/mpl/aux_/clear_impl.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/clear_fwd.hpp>
|
||||
#include <boost/mpl/aux_/traits_lambda_spec.hpp>
|
||||
#include <boost/mpl/aux_/config/eti.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
// no default implementation; the definition is needed to make MSVC happy
|
||||
|
||||
template< typename Tag >
|
||||
struct clear_impl
|
||||
{
|
||||
template< typename Sequence > struct apply;
|
||||
};
|
||||
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, clear_impl)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
|
38
boost/mpl/aux_/config/typeof.hpp
Normal file
38
boost/mpl/aux_/config/typeof.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_CONFIG_TYPEOF_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_CONFIG_TYPEOF_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2003-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/aux_/config/gcc.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_HAS_TYPEOF) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE) \
|
||||
&& ( defined(BOOST_MPL_CFG_GCC) && BOOST_MPL_CFG_GCC >= 0x0302 \
|
||||
|| defined(__MWERKS__) && __MWERKS__ >= 0x3000 \
|
||||
)
|
||||
|
||||
# define BOOST_MPL_CFG_HAS_TYPEOF
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE) \
|
||||
&& defined(BOOST_MPL_CFG_HAS_TYPEOF)
|
||||
|
||||
# define BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MPL_AUX_CONFIG_TYPEOF_HPP_INCLUDED
|
43
boost/mpl/aux_/fold_impl.hpp
Normal file
43
boost/mpl/aux_/fold_impl.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
# include <boost/mpl/next_prior.hpp>
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/deref.hpp>
|
||||
# include <boost/mpl/aux_/config/ctps.hpp>
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
|
||||
# define BOOST_MPL_PREPROCESSED_HEADER fold_impl.hpp
|
||||
# include <boost/mpl/aux_/include_preprocessed.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# define AUX778076_FOLD_IMPL_OP(iter) typename deref<iter>::type
|
||||
# define AUX778076_FOLD_IMPL_NAME_PREFIX fold
|
||||
# include <boost/mpl/aux_/fold_impl_body.hpp>
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
#endif // BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
|
365
boost/mpl/aux_/fold_impl_body.hpp
Normal file
365
boost/mpl/aux_/fold_impl_body.hpp
Normal file
@ -0,0 +1,365 @@
|
||||
|
||||
// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION
|
||||
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
# include <boost/mpl/limits/unrolling.hpp>
|
||||
# include <boost/mpl/aux_/preprocessor/repeat.hpp>
|
||||
# include <boost/mpl/aux_/config/workaround.hpp>
|
||||
# include <boost/mpl/aux_/config/ctps.hpp>
|
||||
# include <boost/mpl/aux_/nttp_decl.hpp>
|
||||
# include <boost/mpl/aux_/config/eti.hpp>
|
||||
|
||||
# include <boost/preprocessor/iterate.hpp>
|
||||
# include <boost/preprocessor/dec.hpp>
|
||||
# include <boost/preprocessor/cat.hpp>
|
||||
|
||||
// local macros, #undef-ined at the end of the header
|
||||
|
||||
# define AUX778076_ITER_FOLD_STEP(unused, i, unused2) \
|
||||
typedef typename apply2< \
|
||||
ForwardOp \
|
||||
, BOOST_PP_CAT(state,i) \
|
||||
, AUX778076_FOLD_IMPL_OP(BOOST_PP_CAT(iter,i)) \
|
||||
>::type BOOST_PP_CAT(state,BOOST_PP_INC(i)); \
|
||||
typedef typename mpl::next<BOOST_PP_CAT(iter,i)>::type \
|
||||
BOOST_PP_CAT(iter,BOOST_PP_INC(i)); \
|
||||
/**/
|
||||
|
||||
# define AUX778076_FOLD_IMPL_NAME \
|
||||
BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_impl) \
|
||||
/**/
|
||||
|
||||
# define AUX778076_FOLD_CHUNK_NAME \
|
||||
BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_chunk) \
|
||||
/**/
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
|
||||
/// forward declaration
|
||||
template<
|
||||
BOOST_MPL_AUX_NTTP_DECL(int, N)
|
||||
, typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME;
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/fold_impl_body.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
|
||||
template<
|
||||
BOOST_MPL_AUX_NTTP_DECL(int, N)
|
||||
, typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME
|
||||
{
|
||||
typedef AUX778076_FOLD_IMPL_NAME<
|
||||
BOOST_MPL_LIMIT_UNROLLING
|
||||
, First
|
||||
, Last
|
||||
, State
|
||||
, ForwardOp
|
||||
> chunk_;
|
||||
|
||||
typedef AUX778076_FOLD_IMPL_NAME<
|
||||
( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
|
||||
, typename chunk_::iterator
|
||||
, Last
|
||||
, typename chunk_::state
|
||||
, ForwardOp
|
||||
> res_;
|
||||
|
||||
typedef typename res_::state state;
|
||||
typedef typename res_::iterator iterator;
|
||||
};
|
||||
|
||||
// fallback implementation for sequences of unknown size
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME<-1,First,Last,State,ForwardOp>
|
||||
: AUX778076_FOLD_IMPL_NAME<
|
||||
-1
|
||||
, typename mpl::next<First>::type
|
||||
, Last
|
||||
, typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
|
||||
, ForwardOp
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
template<
|
||||
typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME<-1,Last,Last,State,ForwardOp>
|
||||
{
|
||||
typedef State state;
|
||||
typedef Last iterator;
|
||||
};
|
||||
|
||||
# else // BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
|
||||
// Borland have some serious problems with the unrolled version, so
|
||||
// we always use a basic implementation
|
||||
template<
|
||||
BOOST_MPL_AUX_NTTP_DECL(int, N)
|
||||
, typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME
|
||||
{
|
||||
typedef AUX778076_FOLD_IMPL_NAME<
|
||||
-1
|
||||
, typename mpl::next<First>::type
|
||||
, Last
|
||||
, typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
|
||||
, ForwardOp
|
||||
> res_;
|
||||
|
||||
typedef typename res_::state state;
|
||||
typedef typename res_::iterator iterator;
|
||||
typedef state type;
|
||||
};
|
||||
|
||||
template<
|
||||
BOOST_MPL_AUX_NTTP_DECL(int, N)
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME<N,Last,Last,State,ForwardOp >
|
||||
{
|
||||
typedef State state;
|
||||
typedef Last iterator;
|
||||
typedef state type;
|
||||
};
|
||||
|
||||
# endif // BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
|
||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
|
||||
struct AUX778076_FOLD_CHUNK_NAME;
|
||||
|
||||
# define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/fold_impl_body.hpp>))
|
||||
# include BOOST_PP_ITERATE()
|
||||
|
||||
// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
|
||||
template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
|
||||
struct AUX778076_FOLD_CHUNK_NAME
|
||||
{
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct result_
|
||||
{
|
||||
typedef AUX778076_FOLD_IMPL_NAME<
|
||||
BOOST_MPL_LIMIT_UNROLLING
|
||||
, First
|
||||
, Last
|
||||
, State
|
||||
, ForwardOp
|
||||
> chunk_;
|
||||
|
||||
typedef AUX778076_FOLD_IMPL_NAME<
|
||||
( (N - BOOST_MPL_LIMIT_UNROLLING) < 0 ? 0 : N - BOOST_MPL_LIMIT_UNROLLING )
|
||||
, typename chunk_::iterator
|
||||
, Last
|
||||
, typename chunk_::state
|
||||
, ForwardOp
|
||||
> res_;
|
||||
|
||||
typedef typename res_::state state;
|
||||
typedef typename res_::iterator iterator;
|
||||
};
|
||||
};
|
||||
|
||||
// fallback implementation for sequences of unknown size
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step);
|
||||
|
||||
template<
|
||||
typename Last
|
||||
, typename State
|
||||
>
|
||||
struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)
|
||||
{
|
||||
typedef Last iterator;
|
||||
typedef State state;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AUX778076_FOLD_CHUNK_NAME<-1>
|
||||
{
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct result_
|
||||
{
|
||||
typedef typename if_<
|
||||
typename is_same<First,Last>::type
|
||||
, BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_null_step)<Last,State>
|
||||
, BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)<First,Last,State,ForwardOp>
|
||||
>::type res_;
|
||||
|
||||
typedef typename res_::state state;
|
||||
typedef typename res_::iterator iterator;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
|
||||
/// ETI workaround
|
||||
template<> struct result_<int,int,int,int>
|
||||
{
|
||||
typedef int state;
|
||||
typedef int iterator;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct BOOST_PP_CAT(AUX778076_FOLD_IMPL_NAME_PREFIX,_step)
|
||||
{
|
||||
// can't inherit here - it breaks MSVC 7.0
|
||||
typedef AUX778076_FOLD_CHUNK_NAME<-1>::template result_<
|
||||
typename mpl::next<First>::type
|
||||
, Last
|
||||
, typename apply2<ForwardOp,State,AUX778076_FOLD_IMPL_OP(First)>::type
|
||||
, ForwardOp
|
||||
> chunk_;
|
||||
|
||||
typedef typename chunk_::state state;
|
||||
typedef typename chunk_::iterator iterator;
|
||||
};
|
||||
|
||||
template<
|
||||
BOOST_MPL_AUX_NTTP_DECL(int, N)
|
||||
, typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME
|
||||
: AUX778076_FOLD_CHUNK_NAME<N>
|
||||
::template result_<First,Last,State,ForwardOp>
|
||||
{
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
}}}
|
||||
|
||||
# undef AUX778076_FOLD_IMPL_NAME
|
||||
# undef AUX778076_FOLD_CHUNK_NAME
|
||||
# undef AUX778076_ITER_FOLD_STEP
|
||||
|
||||
#undef AUX778076_FOLD_IMPL_OP
|
||||
#undef AUX778076_FOLD_IMPL_NAME_PREFIX
|
||||
|
||||
///// iteration
|
||||
|
||||
#else
|
||||
|
||||
# define n_ BOOST_PP_FRAME_ITERATION(1)
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct AUX778076_FOLD_IMPL_NAME<n_,First,Last,State,ForwardOp>
|
||||
{
|
||||
typedef First iter0;
|
||||
typedef State state0;
|
||||
|
||||
BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused)
|
||||
|
||||
typedef BOOST_PP_CAT(state,n_) state;
|
||||
typedef BOOST_PP_CAT(iter,n_) iterator;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<> struct AUX778076_FOLD_CHUNK_NAME<n_>
|
||||
{
|
||||
template<
|
||||
typename First
|
||||
, typename Last
|
||||
, typename State
|
||||
, typename ForwardOp
|
||||
>
|
||||
struct result_
|
||||
{
|
||||
typedef First iter0;
|
||||
typedef State state0;
|
||||
|
||||
BOOST_MPL_PP_REPEAT(n_, AUX778076_ITER_FOLD_STEP, unused)
|
||||
|
||||
typedef BOOST_PP_CAT(state,n_) state;
|
||||
typedef BOOST_PP_CAT(iter,n_) iterator;
|
||||
};
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
|
||||
/// ETI workaround
|
||||
template<> struct result_<int,int,int,int>
|
||||
{
|
||||
typedef int state;
|
||||
typedef int iterator;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
# undef n_
|
||||
|
||||
#endif // BOOST_PP_IS_ITERATING
|
23
boost/mpl/aux_/has_begin.hpp
Normal file
23
boost/mpl/aux_/has_begin.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2002-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_begin, begin, true)
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
|
23
boost/mpl/aux_/has_size.hpp
Normal file
23
boost/mpl/aux_/has_size.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2002-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(size)
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
|
159
boost/mpl/aux_/inserter_algorithm.hpp
Normal file
159
boost/mpl/aux_/inserter_algorithm.hpp
Normal file
@ -0,0 +1,159 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2003-2004
|
||||
// Copyright David Abrahams 2003-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/back_inserter.hpp>
|
||||
#include <boost/mpl/front_inserter.hpp>
|
||||
#include <boost/mpl/push_back.hpp>
|
||||
#include <boost/mpl/push_front.hpp>
|
||||
#include <boost/mpl/back_inserter.hpp>
|
||||
#include <boost/mpl/front_inserter.hpp>
|
||||
#include <boost/mpl/clear.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/aux_/na.hpp>
|
||||
#include <boost/mpl/aux_/common_name_wknd.hpp>
|
||||
#include <boost/mpl/aux_/na_spec.hpp>
|
||||
#include <boost/mpl/aux_/preprocessor/params.hpp>
|
||||
#include <boost/mpl/aux_/preprocessor/default_params.hpp>
|
||||
#include <boost/mpl/aux_/config/ctps.hpp>
|
||||
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
|
||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
# define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \
|
||||
BOOST_MPL_AUX_COMMON_NAME_WKND(name) \
|
||||
template< \
|
||||
BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
|
||||
> \
|
||||
struct name \
|
||||
: aux::name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
|
||||
> \
|
||||
struct name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \
|
||||
: if_< has_push_back< typename clear<P1>::type> \
|
||||
, aux::name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, back_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
, aux::reverse_##name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, front_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
>::type \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template< \
|
||||
BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
|
||||
> \
|
||||
struct reverse_##name \
|
||||
: aux::reverse_##name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
|
||||
> \
|
||||
struct reverse_##name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \
|
||||
: if_< has_push_back<P1> \
|
||||
, aux::reverse_##name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, back_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
, aux::name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, front_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
>::type \
|
||||
{ \
|
||||
}; \
|
||||
BOOST_MPL_AUX_NA_SPEC(arity, name) \
|
||||
BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \
|
||||
/**/
|
||||
|
||||
#else
|
||||
|
||||
# define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \
|
||||
BOOST_MPL_AUX_COMMON_NAME_WKND(name) \
|
||||
template< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
|
||||
> \
|
||||
struct def_##name##_impl \
|
||||
: if_< has_push_back<P1> \
|
||||
, aux::name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, back_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
, aux::reverse_##name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, front_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
>::type \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template< \
|
||||
BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
|
||||
> \
|
||||
struct name \
|
||||
{ \
|
||||
typedef typename eval_if< \
|
||||
is_na<BOOST_PP_CAT(P, arity)> \
|
||||
, def_##name##_impl<BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P)> \
|
||||
, aux::name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
|
||||
>::type type; \
|
||||
}; \
|
||||
\
|
||||
template< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
|
||||
> \
|
||||
struct def_reverse_##name##_impl \
|
||||
: if_< has_push_back<P1> \
|
||||
, aux::reverse_##name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, back_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
, aux::name##_impl< \
|
||||
BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
|
||||
, front_inserter< typename clear<P1>::type > \
|
||||
> \
|
||||
>::type \
|
||||
{ \
|
||||
}; \
|
||||
template< \
|
||||
BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
|
||||
> \
|
||||
struct reverse_##name \
|
||||
{ \
|
||||
typedef typename eval_if< \
|
||||
is_na<BOOST_PP_CAT(P, arity)> \
|
||||
, def_reverse_##name##_impl<BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P)> \
|
||||
, aux::reverse_##name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
|
||||
>::type type; \
|
||||
}; \
|
||||
BOOST_MPL_AUX_NA_SPEC(arity, name) \
|
||||
BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \
|
||||
/**/
|
||||
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
#endif // BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
|
42
boost/mpl/aux_/iter_fold_impl.hpp
Normal file
42
boost/mpl/aux_/iter_fold_impl.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#if !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
# include <boost/mpl/next_prior.hpp>
|
||||
# include <boost/mpl/apply.hpp>
|
||||
# include <boost/mpl/aux_/config/ctps.hpp>
|
||||
# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/type_traits/is_same.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/mpl/aux_/config/use_preprocessed.hpp>
|
||||
|
||||
#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
|
||||
&& !defined(BOOST_MPL_PREPROCESSING_MODE)
|
||||
|
||||
# define BOOST_MPL_PREPROCESSED_HEADER iter_fold_impl.hpp
|
||||
# include <boost/mpl/aux_/include_preprocessed.hpp>
|
||||
|
||||
#else
|
||||
|
||||
# define AUX778076_FOLD_IMPL_OP(iter) iter
|
||||
# define AUX778076_FOLD_IMPL_NAME_PREFIX iter_fold
|
||||
# include <boost/mpl/aux_/fold_impl_body.hpp>
|
||||
|
||||
#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
|
||||
#endif // BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
|
62
boost/mpl/aux_/msvc_type.hpp
Normal file
62
boost/mpl/aux_/msvc_type.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2001-2004
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/aux_/config/eti.hpp>
|
||||
#include <boost/mpl/aux_/is_msvc_eti_arg.hpp>
|
||||
|
||||
namespace boost { namespace mpl { namespace aux {
|
||||
|
||||
#if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
|
||||
|
||||
template< bool > struct msvc_type_impl
|
||||
{
|
||||
template< typename T > struct result_
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
};
|
||||
|
||||
template<> struct msvc_type_impl<true>
|
||||
{
|
||||
template< typename T > struct result_
|
||||
{
|
||||
typedef result_ type;
|
||||
};
|
||||
};
|
||||
|
||||
template< typename T > struct msvc_type
|
||||
: msvc_type_impl< is_msvc_eti_arg<T>::value >
|
||||
::template result_<T>
|
||||
{
|
||||
};
|
||||
|
||||
#else // BOOST_MPL_CFG_MSVC_70_ETI_BUG
|
||||
|
||||
template< typename T > struct msvc_type
|
||||
{
|
||||
typedef typename T::type type;
|
||||
};
|
||||
|
||||
template<> struct msvc_type<int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
|
70
boost/mpl/aux_/push_back_impl.hpp
Normal file
70
boost/mpl/aux_/push_back_impl.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/push_back_fwd.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/aux_/has_type.hpp>
|
||||
#include <boost/mpl/aux_/traits_lambda_spec.hpp>
|
||||
#include <boost/mpl/aux_/config/forwarding.hpp>
|
||||
#include <boost/mpl/aux_/config/static_constant.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
struct has_push_back_arg {};
|
||||
|
||||
// agurt 05/feb/04: no default implementation; the stub definition is needed
|
||||
// to enable the default 'has_push_back' implementation below
|
||||
template< typename Tag >
|
||||
struct push_back_impl
|
||||
{
|
||||
template< typename Sequence, typename T > struct apply
|
||||
{
|
||||
// should be instantiated only in the context of 'has_push_back_impl';
|
||||
// if you've got an assert here, you are requesting a 'push_back'
|
||||
// specialization that doesn't exist.
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
( boost::is_same< T, has_push_back_arg >::value )
|
||||
, REQUESTED_PUSH_BACK_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST
|
||||
, ( Sequence )
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
template< typename Tag >
|
||||
struct has_push_back_impl
|
||||
{
|
||||
template< typename Seq > struct apply
|
||||
#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
|
||||
: aux::has_type< push_back< Seq, has_push_back_arg > >
|
||||
{
|
||||
#else
|
||||
{
|
||||
typedef aux::has_type< push_back< Seq, has_push_back_arg > > type;
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
(aux::has_type< push_back< Seq, has_push_back_arg > >::value)
|
||||
);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_back_impl)
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_back_impl)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
|
71
boost/mpl/aux_/push_front_impl.hpp
Normal file
71
boost/mpl/aux_/push_front_impl.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
#ifndef BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
|
||||
#define BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
|
||||
|
||||
// Copyright Aleksey Gurtovoy 2000-2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/mpl for documentation.
|
||||
|
||||
// $Id$
|
||||
// $Date$
|
||||
// $Revision$
|
||||
|
||||
#include <boost/mpl/push_front_fwd.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/aux_/has_type.hpp>
|
||||
#include <boost/mpl/aux_/traits_lambda_spec.hpp>
|
||||
#include <boost/mpl/aux_/config/forwarding.hpp>
|
||||
#include <boost/mpl/aux_/config/static_constant.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace mpl {
|
||||
|
||||
struct has_push_front_arg {};
|
||||
|
||||
// agurt 05/feb/04: no default implementation; the stub definition is needed
|
||||
// to enable the default 'has_push_front' implementation below
|
||||
|
||||
template< typename Tag >
|
||||
struct push_front_impl
|
||||
{
|
||||
template< typename Sequence, typename T > struct apply
|
||||
{
|
||||
// should be instantiated only in the context of 'has_push_front_impl';
|
||||
// if you've got an assert here, you are requesting a 'push_front'
|
||||
// specialization that doesn't exist.
|
||||
BOOST_MPL_ASSERT_MSG(
|
||||
( boost::is_same< T, has_push_front_arg >::value )
|
||||
, REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST
|
||||
, ( Sequence )
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
template< typename Tag >
|
||||
struct has_push_front_impl
|
||||
{
|
||||
template< typename Seq > struct apply
|
||||
#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
|
||||
: aux::has_type< push_front< Seq, has_push_front_arg > >
|
||||
{
|
||||
#else
|
||||
{
|
||||
typedef aux::has_type< push_front< Seq, has_push_front_arg > > type;
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
(aux::has_type< push_front< Seq, has_push_front_arg > >::value)
|
||||
);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_front_impl)
|
||||
BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_front_impl)
|
||||
|
||||
}}
|
||||
|
||||
#endif // BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user