2 Copyright 2007 John Maddock.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt).
8 [section:examples Examples]
10 [section:copy An Optimized Version of std::copy]
12 Demonstrates a version of `std::copy` that uses `__has_trivial_assign` to
13 determine whether to use `memcpy` to optimise the copy operation
14 (see [@../../examples/copy_example.cpp copy_example.cpp]):
18 // same semantics as std::copy
19 // calls memcpy where appropriate.
24 template<typename I1, typename I2, bool b>
25 I2 copy_imp(I1 first, I1 last, I2 out, const boost::__integral_constant<bool, b>&)
37 T* copy_imp(const T* first, const T* last, T* out, const boost::__true_type&)
39 memmove(out, first, (last-first)*sizeof(T));
40 return out+(last-first);
46 template<typename I1, typename I2>
47 inline I2 copy(I1 first, I1 last, I2 out)
50 // We can copy with memcpy if T has a trivial assignment operator,
51 // and if the iterator arguments are actually pointers (this last
52 // requirement we detect with overload resolution):
54 typedef typename std::iterator_traits<I1>::value_type value_type;
55 return detail::copy_imp(first, last, out, boost::__has_trivial_assign<value_type>());
61 [section:fill An Optimised Version of std::fill]
63 Demonstrates a version of `std::fill` that uses `__has_trivial_assign` to
64 determine whether to use `memset` to optimise the fill operation
65 (see [@../../examples/fill_example.cpp fill_example.cpp]):
69 // same as std::fill, but uses memset where appropriate
73 template <typename I, typename T, bool b>
74 void do_fill(I first, I last, const T& val, const boost::__integral_constant<bool, b>&)
84 void do_fill(T* first, T* last, const T& val, const boost::__true_type&)
86 std::memset(first, val, last-first);
91 template <class I, class T>
92 inline void fill(I first, I last, const T& val)
95 // We can do an optimised fill if T has a trivial assignment
96 // operator and if it's size is one:
98 typedef boost::__integral_constant<bool,
99 ::boost::__has_trivial_assign<T>::value && (sizeof(T) == 1)> truth_type;
100 detail::do_fill(first, last, val, truth_type());
106 [section:destruct An Example that Omits Destructor Calls For Types with Trivial Destructors]
108 Demonstrates a simple algorithm that uses `__has_trivial_destruct` to
109 determine whether to destructors need to be called
110 (see [@../../examples/trivial_destructor_example.cpp trivial_destructor_example.cpp]):
113 // algorithm destroy_array:
114 // The reverse of std::unitialized_copy, takes a block of
115 // initialized memory and calls destructors on all objects therein.
121 void do_destroy_array(T* first, T* last, const boost::__false_type&)
131 inline void do_destroy_array(T* first, T* last, const boost::__true_type&)
135 } // namespace detail
138 inline void destroy_array(T* p1, T* p2)
140 detail::do_destroy_array(p1, p2, ::boost::__has_trivial_destructor<T>());
146 [section:iter An improved Version of std::iter_swap]
148 Demonstrates a version of `std::iter_swap` that use type traits to
149 determine whether an it's arguments are proxy iterators or not,
150 if they're not then it just does a `std::swap` of it's dereferenced
152 same as `std::iter_swap` does), however if they are proxy iterators
153 then takes special care over the swap to ensure that the algorithm
154 works correctly for both proxy iterators, and even iterators of
156 (see [@../../examples/iter_swap_example.cpp iter_swap_example.cpp]):
160 // tests whether iterator is a proxy iterator or not, and
161 // uses optimal form accordingly:
165 template <typename I>
166 static void do_swap(I one, I two, const boost::__false_type&)
168 typedef typename std::iterator_traits<I>::value_type v_t;
173 template <typename I>
174 static void do_swap(I one, I two, const boost::__true_type&)
182 template <typename I1, typename I2>
183 inline void iter_swap(I1 one, I2 two)
186 // See is both arguments are non-proxying iterators,
187 // and if both iterator the same type:
189 typedef typename std::iterator_traits<I1>::reference r1_t;
190 typedef typename std::iterator_traits<I2>::reference r2_t;
192 typedef boost::__integral_constant<bool,
193 ::boost::__is_reference<r1_t>::value
194 && ::boost::__is_reference<r2_t>::value
195 && ::boost::__is_same<r1_t, r2_t>::value> truth_type;
197 detail::do_swap(one, two, truth_type());
203 [section:to_double Convert Numeric Types and Enums to double]
205 Demonstrates a conversion of
206 [@../../../../libs/numeric/conversion/doc/html/boost_numericconversion/definitions.html#boost_numericconversion.definitions.numeric_types
208 and enum types to double:
211 inline double to_double(T const& value)
213 typedef typename boost::promote<T>::type promoted;
214 return boost::numeric::converter<double,promoted>::convert(value);
219 [section:improved_min Improving std::min with common_type]
221 An improved `std::min` function could be written like this:
223 template <class T, class U>
224 typename __common_type<T, U>::type min(T t, U u)
226 return t < u ? t : u;
229 And now expressions such as:
233 will actually compile and return the correct type!