memory revision fd56a38d5dcb569b146634bb22c5d9cb1e138e3f
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_MEMORY__ 31#define ANDROID_ASTL_MEMORY__ 32 33#include "type_traits.h" 34#include <new> // for placement new 35#include <cstring> 36#include <algorithm> 37 38#if defined(_InputIterator) || defined(_ForwardIterator) 39#error "_InputIterator or _ForwardIterator are already defined." 40#endif 41 42namespace std { 43 44// uninitialized_copy is used when memory allocation and object 45// construction need to happen in separate steps. For each instance in 46// the input range a copy is created and placed in the corresponding 47// memory pointed by dest. 48// If the input range is made of pod instances, uninitialized_copy 49// degrades to a memmove call. 50 51template<bool> struct __uninitialized_copy 52{ 53 template<typename _InputIterator, typename _ForwardIterator> 54 static _ForwardIterator *uninitialized_copy(const _InputIterator *begin, 55 const _InputIterator *end, 56 _ForwardIterator *dest) 57 { 58 _ForwardIterator *result = dest; 59 for (; begin < end; ++begin, ++dest) 60 new (static_cast<void*>(dest)) _ForwardIterator(*begin); 61 return result; 62 } 63}; 64 65template<> struct __uninitialized_copy<true> 66{ 67 template<typename _InputIterator, typename _ForwardIterator> 68 static _ForwardIterator *uninitialized_copy(const _InputIterator *begin, 69 const _InputIterator *end, 70 _ForwardIterator *dest) 71 { 72 const ptrdiff_t len = end - begin; 73 const size_t kMaxSizeT = ~((size_t)0); 74 const size_t kSize = sizeof(_InputIterator); 75 76 if (len > 0 && kMaxSizeT / kSize > static_cast<size_t>(len)) 77 { 78 std::memmove(static_cast<void*>(dest), 79 static_cast<const void*>(begin), kSize * len); 80 } 81 return dest; 82 } 83}; 84 85// The real STL takes iterators, we take pointers for now. 86template<typename _InputIterator, typename _ForwardIterator> 87inline _ForwardIterator* uninitialized_copy(const _InputIterator *begin, 88 const _InputIterator *end, 89 _ForwardIterator *dest) 90{ 91 const bool both_pod = 92 is_pod<_InputIterator>::value && is_pod<_ForwardIterator>::value; 93 return __uninitialized_copy<both_pod>::uninitialized_copy(begin, end, dest); 94} 95 96// uninitialized_fill is used when memory allocation and object 97// construction need to happen in separate steps. uninitialized_fill 98// creates a copy of 'obj' in the location pointed by the interator, 99// using the object's class copy constructor. 100 101template<bool> struct __uninitialized_fill 102{ 103 template<typename _ForwardIterator, typename _T> 104 static void uninitialized_fill(_ForwardIterator *begin, 105 _ForwardIterator *end, 106 const _T& val) 107 { 108 for (; begin < end; ++begin) 109 new (static_cast<void*>(begin)) _ForwardIterator(val); 110 } 111}; 112 113template<> struct __uninitialized_fill<true> 114{ 115 template<typename _ForwardIterator, typename _T> 116 static void uninitialized_fill(_ForwardIterator *begin, 117 _ForwardIterator *end, 118 const _T& val) 119 { 120 std::fill(begin, end, val); 121 } 122}; 123 124// The real STL takes iterators, we take pointers for now. 125template<typename _ForwardIterator, typename _T> 126inline void uninitialized_fill(_ForwardIterator *begin, 127 _ForwardIterator *end, 128 const _T& val) 129{ 130 const bool pod = is_pod<_ForwardIterator>::value; 131 return __uninitialized_fill<pod>::uninitialized_fill(begin, end, val); 132} 133 134} // namespace std 135 136#endif // ANDROID_ASTL_MEMORY__ 137