| /** @file |
| |
| A brief file description |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #define FAST_DATA_SIZE 4 |
| |
| template <class T> struct CacheArray { |
| CacheArray(const T *val, int initial_size = 0); |
| ~CacheArray(); |
| |
| operator const T *() const; |
| operator T *(); |
| T &operator[](int idx); |
| T &operator()(int idx); |
| T *detach(); |
| int length(); |
| void clear(); |
| void |
| set_length(int i) |
| { |
| pos = i - 1; |
| } |
| |
| void resize(int new_size); |
| |
| T *data; |
| T fast_data[FAST_DATA_SIZE]; |
| const T *default_val; |
| int size; |
| int pos; |
| }; |
| |
| template <class T> |
| TS_INLINE |
| CacheArray<T>::CacheArray(const T *val, int initial_size) |
| : data(nullptr), default_val(val), size(0), pos(-1) |
| { |
| if (initial_size > 0) { |
| int i = 1; |
| |
| while (i < initial_size) { |
| i <<= 1; |
| } |
| |
| resize(i); |
| } |
| } |
| |
| template <class T> TS_INLINE CacheArray<T>::~CacheArray() |
| { |
| if (data) { |
| if (data != fast_data) { |
| delete[] data; |
| } |
| } |
| } |
| |
| template <class T> TS_INLINE CacheArray<T>::operator const T *() const |
| { |
| return data; |
| } |
| |
| template <class T> |
| TS_INLINE |
| CacheArray<T>::operator T *() |
| { |
| return data; |
| } |
| |
| template <class T> |
| TS_INLINE T & |
| CacheArray<T>::operator[](int idx) |
| { |
| return data[idx]; |
| } |
| |
| template <class T> |
| TS_INLINE T & |
| CacheArray<T>::operator()(int idx) |
| { |
| if (idx >= size) { |
| int new_size; |
| |
| if (size == 0) { |
| new_size = FAST_DATA_SIZE; |
| } else { |
| new_size = size * 2; |
| } |
| |
| if (idx >= new_size) { |
| new_size = idx + 1; |
| } |
| |
| resize(new_size); |
| } |
| |
| if (idx > pos) { |
| pos = idx; |
| } |
| |
| return data[idx]; |
| } |
| |
| template <class T> |
| TS_INLINE T * |
| CacheArray<T>::detach() |
| { |
| T *d; |
| |
| d = data; |
| data = nullptr; |
| |
| return d; |
| } |
| |
| template <class T> |
| TS_INLINE int |
| CacheArray<T>::length() |
| { |
| return pos + 1; |
| } |
| |
| template <class T> |
| TS_INLINE void |
| CacheArray<T>::clear() |
| { |
| if (data) { |
| if (data != fast_data) { |
| delete[] data; |
| } |
| data = nullptr; |
| } |
| |
| size = 0; |
| pos = -1; |
| } |
| |
| template <class T> |
| TS_INLINE void |
| CacheArray<T>::resize(int new_size) |
| { |
| if (new_size > size) { |
| T *new_data; |
| int i; |
| |
| if (new_size > FAST_DATA_SIZE) { |
| new_data = new T[new_size]; |
| } else { |
| new_data = fast_data; |
| } |
| |
| for (i = 0; i < size; i++) { |
| new_data[i] = data[i]; |
| } |
| |
| for (; i < new_size; i++) { |
| new_data[i] = *default_val; |
| } |
| |
| if (data) { |
| if (data != fast_data) { |
| delete[] data; |
| } |
| } |
| data = new_data; |
| size = new_size; |
| } |
| } |