mirror of
https://github.com/boostorg/type_traits.git
synced 2025-07-29 12:07:20 +02:00
Fixed library information in docs.
Updated examples to match new docs. [SVN r28289]
This commit is contained in:
@ -10,6 +10,7 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt
|
||||
</ulink>)
|
||||
]
|
||||
[authors [authors, various]]
|
||||
[category template]
|
||||
[category generic]
|
||||
[last-revision $Date$]
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright John Maddock 1999.
|
||||
* (C) Copyright John Maddock 1999-2005.
|
||||
* 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)
|
||||
@ -19,6 +19,7 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/test/included/prg_exec_monitor.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
@ -36,8 +37,8 @@ namespace opt{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename I1, typename I2>
|
||||
I2 copy_imp(I1 first, I1 last, I2 out)
|
||||
template<typename I1, typename I2, bool b>
|
||||
I2 copy_imp(I1 first, I1 last, I2 out, const boost::integral_constant<bool, b>&)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
@ -48,79 +49,28 @@ I2 copy_imp(I1 first, I1 last, I2 out)
|
||||
return out;
|
||||
}
|
||||
|
||||
template <bool b>
|
||||
struct copier
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2 do_copy(I1 first, I1 last, I2 out)
|
||||
{ return copy_imp(first, last, out); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct copier<true>
|
||||
{
|
||||
template<typename I1, typename I2>
|
||||
static I2* do_copy(I1* first, I1* last, I2* out)
|
||||
{
|
||||
memcpy(out, first, (last-first)*sizeof(I2));
|
||||
return out+(last-first);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I1>::value_type>::type v1_t;
|
||||
typedef typename boost::remove_cv<typename std::iterator_traits<I2>::value_type>::type v2_t;
|
||||
return detail::copier<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_same<v1_t, v2_t>::value,
|
||||
::boost::is_pointer<I1>::value,
|
||||
::boost::is_pointer<I2>::value,
|
||||
::boost::has_trivial_assign<v1_t>::value
|
||||
>::value>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
#else // BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
//
|
||||
// If there is no standard iterator_traits then we have to
|
||||
// use overloading rather than iterator_traits to detect
|
||||
// when we have T*'s to copy. Note that we cannot overload
|
||||
// copy directly as that will cause some standard conforming
|
||||
// code to fail to build:
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy_(const I1& first, const I1& last, const I2& out)
|
||||
{
|
||||
return detail::copier<false>::do_copy(first, last, out);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T* copy_(const T*& first, const T*& last, T*& out)
|
||||
T* copy_imp(const T* first, const T* last, T* out, const boost::true_type&)
|
||||
{
|
||||
return detail::copier<
|
||||
::boost::has_trivial_assign<T>::value
|
||||
>::do_copy(first, last, out);
|
||||
memcpy(out, first, (last-first)*sizeof(T));
|
||||
return out+(last-first);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}
|
||||
|
||||
template<typename I1, typename I2>
|
||||
inline I2 copy(I1 first, I1 last, I2 out)
|
||||
{
|
||||
return detail::copy_(first, last, out);
|
||||
//
|
||||
// We can copy with memcpy if T has a trivial assignment operator,
|
||||
// and if the iterator arguments are actually pointers (this last
|
||||
// requirement we detect with overload resolution):
|
||||
//
|
||||
typedef typename std::iterator_traits<I1>::value_type value_type;
|
||||
return detail::copy_imp(first, last, out, boost::has_trivial_assign<value_type>());
|
||||
}
|
||||
|
||||
#endif // BOOST_NO_STD_ITERATOR_TRAITS
|
||||
|
||||
}; // namespace opt
|
||||
|
||||
//
|
||||
@ -176,18 +126,6 @@ int cpp_main(int argc, char* argv[])
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const int*, int*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::detail::copier<false>::do_copy(ci_array, ci_array + array_size, i_array);
|
||||
|
||||
// time unoptimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::do_copy(ci_array, ci_array + array_size, i_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
// cache load:
|
||||
opt::copy(cc_array, cc_array + array_size, c_array);
|
||||
|
||||
@ -212,18 +150,6 @@ int cpp_main(int argc, char* argv[])
|
||||
result = t.elapsed();
|
||||
cout << "std::copy<const char*, char*>: " << result << endl;
|
||||
|
||||
// cache load:
|
||||
opt::detail::copier<false>::do_copy(cc_array, cc_array + array_size, c_array);
|
||||
|
||||
// time unoptimised version:
|
||||
t.restart();
|
||||
for(i = 0; i < iter_count; ++i)
|
||||
{
|
||||
opt::detail::copier<false>::do_copy(cc_array, cc_array + array_size, c_array);
|
||||
}
|
||||
result = t.elapsed();
|
||||
cout << "standard \"unoptimised\" copy: " << result << endl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright John Maddock 1999.
|
||||
* (C) Copyright John Maddock 1999-2005.
|
||||
* 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)
|
||||
@ -20,9 +20,9 @@
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/test/included/prg_exec_monitor.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE) || (defined(std) && defined(__SGI_STL_PORT))
|
||||
namespace std{ using :: memset; }
|
||||
@ -35,13 +35,12 @@ using std::cin;
|
||||
namespace opt{
|
||||
//
|
||||
// fill
|
||||
// same as std::fill, uses memset where appropriate, along with call_traits
|
||||
// to "optimise" parameter passing.
|
||||
// same as std::fill, but uses memset where appropriate
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <typename I, typename T>
|
||||
void do_fill_(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
template <typename I, typename T, bool b>
|
||||
void do_fill(I first, I last, const T& val, const boost::integral_constant<bool, b>&)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
@ -50,43 +49,24 @@ void do_fill_(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
}
|
||||
}
|
||||
|
||||
template <bool opt>
|
||||
struct filler
|
||||
template <typename T>
|
||||
void do_fill(T* first, T* last, const T& val, const boost::true_type&)
|
||||
{
|
||||
template <typename I, typename T>
|
||||
struct rebind
|
||||
{
|
||||
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
|
||||
{ do_fill_<I,T>(first, last, val); }
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct filler<true>
|
||||
{
|
||||
template <typename I, typename T>
|
||||
struct rebind
|
||||
{
|
||||
static void do_fill(I first, I last, T val)
|
||||
{
|
||||
std::memset(first, val, last-first);
|
||||
}
|
||||
};
|
||||
};
|
||||
std::memset(first, val, last-first);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class I, class T>
|
||||
inline void fill(I first, I last, const T& val)
|
||||
{
|
||||
typedef detail::filler<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_pointer<I>::value,
|
||||
::boost::is_arithmetic<T>::value,
|
||||
(sizeof(T) == 1)
|
||||
>::value> filler_t;
|
||||
typedef typename filler_t:: template rebind<I,T> binder;
|
||||
binder::do_fill(first, last, val);
|
||||
//
|
||||
// We can do an optimised fill if T has a trivial assignment
|
||||
// operator and if it's size is one:
|
||||
//
|
||||
typedef boost::integral_constant<bool,
|
||||
::boost::has_trivial_assign<T>::value && (sizeof(T) == 1)> truth_type;
|
||||
detail::do_fill(first, last, val, truth_type());
|
||||
}
|
||||
|
||||
}; // namespace opt
|
||||
@ -150,8 +130,7 @@ int cpp_main(int argc, char* argv[])
|
||||
result = t.elapsed();
|
||||
cout << "std::fill<char*, char>: " << result << endl << endl;
|
||||
|
||||
cout << "testing fill(int)...\n"
|
||||
"[Tests the effect of call_traits pass-by-value optimisation -\nthe value of this optimisation may depend upon hardware characteristics.]" << endl;
|
||||
cout << "testing fill(int)...\n" << endl;
|
||||
|
||||
// cache load:
|
||||
opt::fill(i_array, i_array + array_size, 3);
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright John Maddock 1999.
|
||||
* (C) Copyright John Maddock 1999-2005.
|
||||
* 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)
|
||||
@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/test/included/prg_exec_monitor.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
using std::cout;
|
||||
@ -37,47 +38,39 @@ namespace opt{
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <bool b>
|
||||
struct swapper
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two, const boost::false_type&)
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type v_t;
|
||||
v_t v = *one;
|
||||
*one = *two;
|
||||
*two = v;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
using std::swap;
|
||||
#endif
|
||||
|
||||
template <>
|
||||
struct swapper<true>
|
||||
typedef typename std::iterator_traits<I>::value_type v_t;
|
||||
v_t v = *one;
|
||||
*one = *two;
|
||||
*two = v;
|
||||
}
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two, const boost::true_type&)
|
||||
{
|
||||
template <typename I>
|
||||
static void do_swap(I one, I two)
|
||||
{
|
||||
using std::swap;
|
||||
swap(*one, *two);
|
||||
}
|
||||
};
|
||||
using std::swap;
|
||||
swap(*one, *two);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename I1, typename I2>
|
||||
inline void iter_swap(I1 one, I2 two)
|
||||
{
|
||||
//
|
||||
// See is both arguments are non-proxying iterators,
|
||||
// and if both iterator the same type:
|
||||
//
|
||||
typedef typename std::iterator_traits<I1>::reference r1_t;
|
||||
typedef typename std::iterator_traits<I2>::reference r2_t;
|
||||
detail::swapper<
|
||||
::boost::type_traits::ice_and<
|
||||
::boost::is_reference<r1_t>::value,
|
||||
::boost::is_reference<r2_t>::value,
|
||||
::boost::is_same<r1_t, r2_t>::value
|
||||
>::value>::do_swap(one, two);
|
||||
|
||||
typedef boost::integral_constant<bool,
|
||||
::boost::is_reference<r1_t>::value
|
||||
&& ::boost::is_reference<r2_t>::value
|
||||
&& ::boost::is_same<r1_t, r2_t>::value> truth_type;
|
||||
|
||||
detail::do_swap(one, two, truth_type());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright John Maddock 1999.
|
||||
* (C) Copyright John Maddock 1999-2005.
|
||||
* 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)
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/test/included/prg_exec_monitor.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
@ -33,22 +33,8 @@ namespace opt{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <bool>
|
||||
struct array_destroyer
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct array_destroyer<true>
|
||||
{
|
||||
template <class T>
|
||||
static void destroy_array(T*, T*){}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void do_destroy_array(T* first, T* last)
|
||||
void do_destroy_array(T* first, T* last, const boost::false_type&)
|
||||
{
|
||||
while(first != last)
|
||||
{
|
||||
@ -57,12 +43,17 @@ void do_destroy_array(T* first, T* last)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void do_destroy_array(T* first, T* last, const boost::true_type&)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T>
|
||||
inline void destroy_array(T* p1, T* p2)
|
||||
{
|
||||
detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
|
||||
detail::do_destroy_array(p1, p2, ::boost::has_trivial_destructor<T>());
|
||||
}
|
||||
|
||||
//
|
||||
|
Reference in New Issue
Block a user