algorithm revision 8b5f35d0aa39e39119dc1e3e2fc4d283995faa2a
1/* -*- c++ -*- */ 2/* 3 * Copyright (C) 2009 The Android Open Source Project 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#ifndef ANDROID_ASTL_ALGORITHM__ 31#define ANDROID_ASTL_ALGORITHM__ 32 33#include <cstddef> 34#include <cstring> 35#include <type_traits.h> 36#ifndef ANDROID_ASTL_TYPE_TRAITS_H__ 37#error "Wrong file included!" 38#endif 39 40namespace std { 41 42// This file contains the following template functions: 43// - min 44// - max 45// - swap 46// - fill 47// - fill_n 48// - equal 49 50template<typename _T> inline const _T& min(const _T& left, const _T& right) 51{ 52 if (left < right) return left; 53 return right; 54} 55 56template<typename _T> inline const _T& max(const _T& left, const _T& right) 57{ 58 if (right < left) return left; 59 return right; 60} 61 62template<typename _T> inline void swap(_T& left, _T& right) 63{ 64 _T tmp = left; 65 left = right; 66 right = tmp; 67} 68 69// fill the range [begin, end) with copies of value, return nothing. 70// fill_n the range [begin, begin + n) with copies of value, return 71// the pointer at begin + n. 72// 73// TODO: fill and fill_n should take forward and output iterators for 74// begin and end params. Fix this when iterator are defined. 75 76 77template<bool> struct __fill 78{ 79 template<typename _T> static void fill(_T *begin, const _T *end, 80 const _T& value) 81 { 82 for (; begin < end; ++begin) 83 *begin = value; 84 } 85}; 86 87template<> struct __fill<true> // scalar version 88{ 89 template<typename _T> static void fill(_T *begin, const _T *end, 90 const _T& value) 91 { 92 const _T tmp = value; 93 94 for (; begin < end; ++begin) 95 *begin = tmp; 96 } 97}; 98 99template<typename _T> void fill(_T *begin, _T *end, const _T& value) 100{ 101 const bool is_scalar = std::is_scalar<_T>::value; 102 __fill<is_scalar>::fill(begin, end, value); 103} 104 105// Specialization: for one-byte types use memset. 106inline void fill(unsigned char *begin, unsigned char *end, 107 const unsigned char& value) 108{ 109 if (begin < end) 110 { 111 const int tmp = value; 112 std::memset(begin, tmp, end - begin); 113 } 114} 115 116inline void fill(signed char *begin, signed char *end, const signed char& value) 117{ 118 if (begin < end) 119 { 120 const int tmp = value; 121 std::memset(begin, tmp, end - begin); 122 } 123} 124 125inline void fill(char *begin, char *end, const char& value) 126{ 127 if (begin < end) 128 { 129 const int tmp = value; 130 std::memset(begin, tmp, end - begin); 131 } 132} 133 134template<bool> struct __fill_n 135{ 136 template<typename _T> static _T *fill_n(_T *begin, size_t num, 137 const _T& value) 138 { 139 for (size_t i = 0; i < num; ++i, ++begin) 140 { 141 *begin = value; 142 } 143 return begin; 144 } 145}; 146 147template<> struct __fill_n<true> // scalar version 148{ 149 template<typename _T> static _T *fill_n(_T *begin, size_t num, 150 const _T& value) 151 { 152 const _T tmp = value; 153 154 for (size_t i = 0; i < num; ++i, ++begin) 155 { 156 *begin = tmp; 157 } 158 return begin; 159 } 160}; 161 162template<typename _T> _T *fill_n(_T *begin, size_t n, const _T& value) 163{ 164 const bool is_scalar = std::is_scalar<_T>::value; 165 return __fill_n<is_scalar>::fill_n(begin, n, value); 166} 167 168 169// Specialization: for one-byte types uses memset. 170inline unsigned char *fill_n(unsigned char *begin, size_t num, 171 const unsigned char& value) 172{ 173 const int tmp = value; 174 std::memset(begin, tmp, num); 175 return begin + num; 176} 177 178inline signed char *fill_n(signed char *begin, size_t num, 179 const signed char& value) 180{ 181 const int tmp = value; 182 std::memset(begin, tmp, num); 183 return begin + num; 184} 185 186inline char *fill_n(char *begin, size_t num, const char& value) 187{ 188 const int tmp = value; 189 std::memset(begin, tmp, num); 190 return begin + num; 191} 192 193 194// Test a range for element-wise equality using operator== 195// @param begin1 An input iterator. 196// @param end1 An input iterator. 197// @param begin2 An input iterator. 198// @return true if all the elements of the range are equal. 199// TODO: When we have a proper structure for iterator as opposed to 200// just pointers, we should be able to the get the type for the values 201// referenced by the iterator and default to memcmp for simple types. 202template<typename _InputIterator1, typename _InputIterator2> 203inline bool equal(_InputIterator1 begin1, _InputIterator1 end1, 204 _InputIterator2 begin2) 205{ 206 for (; begin1 < end1; ++begin1, ++begin2) 207 { 208 if (!(*begin1 == *begin2)) 209 { 210 return false; 211 } 212 } 213 return true; 214} 215 216// Test a range for element-wise equality using operator== 217// @param begin1 An input iterator. 218// @param end1 An input iterator. 219// @param begin2 An input iterator. 220// @param binary_pred A binary predicate function. 221// @return true if all the elements of the range are equal. 222template<typename _InputIterator1, typename _InputIterator2, typename _BinaryPredicated> 223inline bool equal(_InputIterator1 begin1, _InputIterator1 end1, 224 _InputIterator2 begin2, _BinaryPredicated binary_predicate) 225{ 226 for (; begin1 < end1; ++begin1, ++begin2) 227 { 228 if (!bool(binary_predicate(*begin1, *begin2))) 229 { 230 return false; 231 } 232 } 233 return true; 234} 235 236} // namespace std 237 238 239#endif 240