text: /**
   * Copyright (c) 2021 OceanBase
   * OceanBase CE is licensed under Mulan PubL v2.
   * You can use this software according to the terms and conditions of the Mulan PubL v2.
   * You may obtain a copy of Mulan PubL v2 at:
   *          http://license.coscl.org.cn/MulanPubL-2.0
   * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
   * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
   * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
   * See the Mulan PubL v2 for more details.
   */
  
  #ifndef _OB_ARRAY_WRAP_H
  #define _OB_ARRAY_WRAP_H 1
  #include <cstdint>
  #include "lib/oblog/ob_log.h"
  #include "lib/allocator/ob_allocator.h"
  #include "lib/utility/ob_macro_utils.h"
  
  namespace oceanbase {
  namespace common {
  template <class T>
  int databuff_print_obj_array(
      char* buf, const int64_t buf_len, int64_t& pos, const T* obj, const int64_t size);  // from ob_print_utils.h
  /// Utility tempalte class to adapt C array to an object, which can be used with databuff_print_obj
  template <typename T>
  class ObIArrayWrap {
  public:
    ObIArrayWrap() : data_(NULL), count_(0)
    {}
    ObIArrayWrap(T* data, const int64_t count) : data_(data), count_(count)
    {}
  
    virtual ~ObIArrayWrap()
    {}
    inline const T& at(int64_t idx) const
    {
  #ifndef NDEBUG
      extra_access_check();
  #endif
      OB_ASSERT(idx >= 0 && idx < count_);
      return data_[idx];
    }
    inline T& at(int64_t idx)
    {
  #ifndef NDEBUG
      extra_access_check();
  #endif
      OB_ASSERT(idx >= 0 && idx < count_);
      return data_[idx];
    }
    inline int64_t count() const
    {
      return count_;
    }
    inline bool empty() const
    {
      return 0 == count();
    }
  
    // extra check for at() in DEBUG building.
    virtual void extra_access_check() const = 0;
  
    T* get_data() const
    {
      return data_;
    }
  
  protected:
    // Expose %data_ and %count_ here to make at(), count() be inlined,
    // derived class should set then appropriatly
    T* data_;
    int64_t count_;
    DISALLOW_COPY_AND_ASSIGN(ObIArrayWrap);
  };
  
  template <typename T>
  class ObArrayWrap final : public ObIArrayWrap<T> {
  public:
    using ObIArrayWrap<T>::count;
    using ObIArrayWrap<T>::at;
  
    ObArrayWrap()
    {}
    ObArrayWrap(const T* objs, const int64_t num) : ObIArrayWrap<T>(const_cast<T*>(objs), num)
    {}
    virtual ~ObArrayWrap()
    {}
  
    inline void reset()
    {
      data_ = NULL;
      count_ = 0;
    }
  
    int allocate_array(ObIAllocator& allocator, int64_t num)
    {
      int ret = OB_SUCCESS;
      void* ptr = NULL;
      int64_t size = num * sizeof(T);
      if (OB_UNLIKELY(num <= 0)) {
        ret = OB_INVALID_ARGUMENT;
        LIB_LOG(WARN, "invalid argument", K(num), K(ret));
      } else if (OB_ISNULL(ptr = allocator.alloc(size))) {
        ret = OB_ALLOCATE_MEMORY_FAILED;
        LIB_LOG(WARN, "allocate memory failed", K(size), K(num));
      } else {
        data_ = new (ptr) T[num];
        count_ = num;
      }
      return ret;
    }
  
    virtual void extra_access_check() const override
    {}
  
    void release_array()
    {
      if (data_ != NULL) {
        for (int64_t i = 0; i < count_; ++i) {
          data_[i].~T();
        }
        count_ = 0;
        data_ = NULL;
      }
    }
  
    int64_t to_string(char* buf, const int64_t buf_len) const
    {
      int ret = OB_SUCCESS;
      int64_t pos = 0;
      if (OB_FAIL(databuff_print_obj_array(buf, buf_len, pos, data_, count_))) {
      } else {
      }
      return pos;
    }
  
    ObArrayWrap& operator=(const ObArrayWrap<T>& other)
    {
      data_ = other.data_;
      count_ = other.count_;
      return *this;
    }
  
    int assign(const ObArrayWrap<T>& other)
    {
      int ret = OB_SUCCESS;
      data_ = other.data_;
      count_ = other.count_;
      return ret;
    }
  
  protected:
    using ObIArrayWrap<T>::data_;
    using ObIArrayWrap<T>::count_;
  };
  
  }  // namespace common
  }  // namespace oceanbase
  
  #endif /* _OB_ARRAY_WRAP_H */
  