algorithm revision df7611a3647a8ac956044c86178fb5ad85d89293
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 49template<typename _T> inline const _T& min(const _T& left, const _T& right) 50{ 51 if (left < right) return left; 52 return right; 53} 54 55template<typename _T> inline const _T& max(const _T& left, const _T& right) 56{ 57 if (right < left) return left; 58 return right; 59} 60 61template<typename _T> inline void swap(_T& left, _T& right) 62{ 63 _T tmp = left; 64 left = right; 65 right = tmp; 66} 67 68// fill the range [begin, end) with copies of value, return nothing. 69// fill_n the range [begin, begin + n) with copies of value, return 70// the pointer at begin + n. 71// 72// TODO: fill and fill_n should take forward and output iterators for 73// begin and end params. Fix this when iterator are defined. 74 75 76template<bool> struct __fill 77{ 78 template<typename _T> static void fill(_T *begin, const _T *end, 79 const _T& value) 80 { 81 for (; begin < end; ++begin) 82 *begin = value; 83 } 84}; 85 86template<> struct __fill<true> // scalar version 87{ 88 template<typename _T> static void fill(_T *begin, const _T *end, 89 const _T& value) 90 { 91 const _T tmp = value; 92 93 for (; begin < end; ++begin) 94 *begin = tmp; 95 } 96}; 97 98template<typename _T> void fill(_T *begin, _T *end, const _T& value) 99{ 100 const bool is_scalar = std::is_scalar<_T>::value; 101 __fill<is_scalar>::fill(begin, end, value); 102} 103 104// Specialization: for one-byte types use memset. 105inline void fill(unsigned char *begin, unsigned char *end, 106 const unsigned char& value) 107{ 108 if (begin < end) 109 { 110 const int tmp = value; 111 std::memset(begin, tmp, end - begin); 112 } 113} 114 115inline void fill(signed char *begin, signed char *end, const signed char& value) 116{ 117 if (begin < end) 118 { 119 const int tmp = value; 120 std::memset(begin, tmp, end - begin); 121 } 122} 123 124inline void fill(char *begin, char *end, const char& value) 125{ 126 if (begin < end) 127 { 128 const int tmp = value; 129 std::memset(begin, tmp, end - begin); 130 } 131} 132 133template<bool> struct __fill_n 134{ 135 template<typename _T> static _T *fill_n(_T *begin, size_t num, 136 const _T& value) 137 { 138 for (size_t i = 0; i < num; ++i, ++begin) 139 { 140 *begin = value; 141 } 142 return begin; 143 } 144}; 145 146template<> struct __fill_n<true> // scalar version 147{ 148 template<typename _T> static _T *fill_n(_T *begin, size_t num, 149 const _T& value) 150 { 151 const _T tmp = value; 152 153 for (size_t i = 0; i < num; ++i, ++begin) 154 { 155 *begin = tmp; 156 } 157 return begin; 158 } 159}; 160 161template<typename _T> _T *fill_n(_T *begin, size_t n, const _T& value) 162{ 163 const bool is_scalar = std::is_scalar<_T>::value; 164 return __fill_n<is_scalar>::fill_n(begin, n, value); 165} 166 167 168// Specialization: for one-byte types uses memset. 169inline unsigned char *fill_n(unsigned char *begin, size_t num, 170 const unsigned char& value) 171{ 172 const int tmp = value; 173 std::memset(begin, tmp, num); 174 return begin + num; 175} 176 177inline signed char *fill_n(signed char *begin, size_t num, 178 const signed char& value) 179{ 180 const int tmp = value; 181 std::memset(begin, tmp, num); 182 return begin + num; 183} 184 185inline char *fill_n(char *begin, size_t num, const char& value) 186{ 187 const int tmp = value; 188 std::memset(begin, tmp, num); 189 return begin + num; 190} 191 192} // namespace std 193 194 195#endif 196