175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi/*
275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * Copyright (C) 2014 The Android Open Source Project
375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *
475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * you may not use this file except in compliance with the License.
675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * You may obtain a copy of the License at
775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *
875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *      http://www.apache.org/licenses/LICENSE-2.0
975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *
1075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
1175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
1275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * See the License for the specific language governing permissions and
1475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * limitations under the License.
1575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi */
1675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
1775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#ifndef LATINIME_INT_ARRAY_VIEW_H
1875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#define LATINIME_INT_ARRAY_VIEW_H
1975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
207eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi#include <algorithm>
21a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi#include <array>
2275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#include <cstdint>
23a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi#include <cstring>
2475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#include <vector>
2575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
2675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#include "defines.h"
2775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
2875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanaginamespace latinime {
2975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
3075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi/**
3175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * Helper class used to provide a read-only view of a given range of integer array. This class
3275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * does not take ownership of the underlying integer array but is designed to be a lightweight
3375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * object that obeys value semantics.
3475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *
3575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * Example:
3675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * <code>
3775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * bool constinsX(IntArrayView view) {
3875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *     for (size_t i = 0; i < view.size(); ++i) {
3975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *         if (view[i] == 'X') {
4075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *             return true;
4175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *         }
4275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *     }
4375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *     return false;
4475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * }
4575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi *
4675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * const int codePointArray[] = { 'A', 'B', 'X', 'Z' };
4775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * auto view = IntArrayView(codePointArray, NELEMS(codePointArray));
4875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * const bool hasX = constinsX(view);
4975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi * </code>
5075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi */
5175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagiclass IntArrayView {
5275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi public:
5375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    IntArrayView() : mPtr(nullptr), mSize(0) {}
5475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
5575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    IntArrayView(const int *const ptr, const size_t size)
5675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi            : mPtr(ptr), mSize(size) {}
5775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
5875d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    explicit IntArrayView(const std::vector<int> &vector)
5975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi            : mPtr(vector.data()), mSize(vector.size()) {}
6075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
61537f6eea8a8d56fe532913a37f4dbff4b3d490afKeisuke Kuroyanagi    template <size_t N>
62537f6eea8a8d56fe532913a37f4dbff4b3d490afKeisuke Kuroyanagi    AK_FORCE_INLINE static IntArrayView fromArray(const std::array<int, N> &array) {
63537f6eea8a8d56fe532913a37f4dbff4b3d490afKeisuke Kuroyanagi        return IntArrayView(array.data(), array.size());
649069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagi    }
659069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagi
66395fe8e98dc102fcad52ef34d281e83e3cd13f46Keisuke Kuroyanagi    // Returns a view that points one int object.
67395fe8e98dc102fcad52ef34d281e83e3cd13f46Keisuke Kuroyanagi    AK_FORCE_INLINE static IntArrayView singleElementView(const int *const ptr) {
68395fe8e98dc102fcad52ef34d281e83e3cd13f46Keisuke Kuroyanagi        return IntArrayView(ptr, 1);
699069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagi    }
709069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagi
7175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    AK_FORCE_INLINE int operator[](const size_t index) const {
7275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi        ASSERT(index < mSize);
7375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi        return mPtr[index];
7475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    }
7575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
7608894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagi    AK_FORCE_INLINE bool empty() const {
7708894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagi        return size() == 0;
7808894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagi    }
7908894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagi
8075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    AK_FORCE_INLINE size_t size() const {
8175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi        return mSize;
8275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    }
8375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
8475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    AK_FORCE_INLINE const int *data() const {
8575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi        return mPtr;
8675d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    }
8775d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
8803dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi    AK_FORCE_INLINE const int *begin() const {
8903dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi        return mPtr;
9003dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi    }
9103dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi
9203dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi    AK_FORCE_INLINE const int *end() const {
9303dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi        return mPtr + mSize;
9403dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi    }
9503dc44f543795040a092723085fac1209103b7bdKeisuke Kuroyanagi
967eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi    AK_FORCE_INLINE bool contains(const int value) const {
977eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi        return std::find(begin(), end(), value) != end();
987eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi    }
997eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi
1009a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    // Returns the view whose size is smaller than or equal to the given count.
1017eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi    AK_FORCE_INLINE const IntArrayView limit(const size_t maxSize) const {
1029a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi        return IntArrayView(mPtr, std::min(maxSize, mSize));
1039a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi    }
1049a23f0fba25137760a60e9bfaf6bf20a5889648cKeisuke Kuroyanagi
1057eb6e28b9eb8e88159affac9ebe2c6c02874c5a3Keisuke Kuroyanagi    AK_FORCE_INLINE const IntArrayView skip(const size_t n) const {
106e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi        if (mSize <= n) {
107e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi            return IntArrayView();
108e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi        }
109e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi        return IntArrayView(mPtr + n, mSize - n);
110e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi    }
111e394a0c6ff96edc8f8c949f0851a26922983f288Keisuke Kuroyanagi
112a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi    template <size_t N>
113a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi    void copyToArray(std::array<int, N> *const buffer, const size_t offset) const {
114a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi        ASSERT(mSize + offset <= N);
115a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi        memmove(buffer->data() + offset, mPtr, sizeof(int) * mSize);
116a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi    }
117a3b0eb168567c2650b024366f95f6b9b0ff1c811Keisuke Kuroyanagi
11809c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi    AK_FORCE_INLINE int firstOrDefault(const int defaultValue) const {
11909c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        if (empty()) {
12009c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi            return defaultValue;
12109c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        }
12209c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        return mPtr[0];
12309c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi    }
12409c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi
12509c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi    AK_FORCE_INLINE int lastOrDefault(const int defaultValue) const {
12609c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        if (empty()) {
12709c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi            return defaultValue;
12809c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        }
12909c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi        return mPtr[mSize - 1];
13009c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi    }
13109c154925f1fd01d46ed67ad2faed41efba5a5aeKeisuke Kuroyanagi
1322842e50c4b454f44cfb49a59b4ba2c13816a876dKeisuke Kuroyanagi    AK_FORCE_INLINE std::vector<int> toVector() const {
1332842e50c4b454f44cfb49a59b4ba2c13816a876dKeisuke Kuroyanagi        return std::vector<int>(begin(), end());
1342842e50c4b454f44cfb49a59b4ba2c13816a876dKeisuke Kuroyanagi    }
1352842e50c4b454f44cfb49a59b4ba2c13816a876dKeisuke Kuroyanagi
136580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi    std::vector<IntArrayView> split(const int separator, const int limit = S_INT_MAX) const {
137580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        if (limit <= 0) {
138580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi            return std::vector<IntArrayView>();
139580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        }
140580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        std::vector<IntArrayView> result;
141580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        if (limit == 1) {
142580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi            result.emplace_back(mPtr, mSize);
143580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi            return result;
144580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        }
145580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        size_t startIndex = 0;
146580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        for (size_t i = 0; i < mSize; ++i) {
147580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi            if (mPtr[i] == separator) {
148580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi                result.emplace_back(mPtr + startIndex, i - startIndex);
149580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi                startIndex = i + 1;
150580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi                if (result.size() >= static_cast<size_t>(limit - 1)) {
151580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi                    break;
152580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi                }
153580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi            }
154580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        }
155580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        result.emplace_back(mPtr + startIndex, mSize - startIndex);
156580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi        return result;
157580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi    }
158580420d21b5b2c40d662d22bc452c2bd4f74d664Keisuke Kuroyanagi
15975d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi private:
16075d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    DISALLOW_ASSIGNMENT_OPERATOR(IntArrayView);
16175d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
16275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    const int *const mPtr;
16375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi    const size_t mSize;
16475d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi};
16575d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi
16608894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagiusing WordIdArrayView = IntArrayView;
1679069d30043d5182dfd38465ad9bbc11ad73fab7cKeisuke Kuroyanagiusing PtNodePosArrayView = IntArrayView;
1686ae4d79d81aa7aea5529d95bb3eb960a273ef411Keisuke Kuroyanagiusing CodePointArrayView = IntArrayView;
169537f6eea8a8d56fe532913a37f4dbff4b3d490afKeisuke Kuroyanagitemplate <size_t size>
170537f6eea8a8d56fe532913a37f4dbff4b3d490afKeisuke Kuroyanagiusing WordIdArray = std::array<int, size>;
17108894842662eff666a713a7f4deb79204a322f8cKeisuke Kuroyanagi
17275d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi} // namespace latinime
17375d8c20d03f8300946c5e4a4832117530110910bKeisuke Kuroyanagi#endif // LATINIME_MEMORY_VIEW_H
174