/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * File: arrays.h
 * Author: pgess <v.melnychenko@xreate.org>
 *
 * Created in March 2020.
 */

#ifndef XREATE_ARRAYSIR_H
#define XREATE_ARRAYSIR_H

#include "compilation/containers.h"

namespace xreate { namespace containers{

class IFwdIteratorIR;

/** \brief The contiguous container implementation.
 *
 *  Represents contiguous in memory(array) implementation.
 *  \sa xreate::containers::IFwdIteratorIR, \sa xreate::containers::Query
 */
class ArrayIR : public IContainersIR{
  friend class FwdIteratorIR<SOLID>;

public:
  ArrayIR(const ExpandedType &aggrT, const typehints::ArrayHint &hints, const compilation::Context &context)
    : __context(context), __aggrT(aggrT), __hint(hints){}

  virtual llvm::Value *init(const std::string &hintAlias = "") override;
  virtual llvm::Value *update(llvm::Value *aggrRaw, const Expression &updE, const std::string &hintAlias) override;
  virtual IFwdIteratorIR* getFwdIterator() override;
  llvm::Value *get(llvm::Value *aggrRaw, std::vector<llvm::Value *> idxL, const std::string &hintAlias);
  static llvm::PointerType *getRawType(const ExpandedType& aggrT, const typehints::ArrayHint& hint, LLVMLayer* llvm);

  /** \brief `loop map` statement compilation*/
  llvm::Value* operatorMap(const Expression& expr, const std::string& hintAlias);

private:
  compilation::Context __context;
  ExpandedType __aggrT;
  typehints::ArrayHint __hint;
};

template<>
class FwdIteratorIR<SOLID>: public IFwdIteratorIR  {
public:
  FwdIteratorIR(const ArrayIR& arraysIR): __compiler(arraysIR) {};

  virtual llvm::Value* begin(llvm::Value* aggrRaw) override;
  virtual llvm::Value* end(llvm::Value* aggrRaw) override;
  virtual llvm::Value* get(llvm::Value* aggrRaw, llvm::Value *idxRaw, const std::string &hintAlias="") override;
  virtual llvm::Value* advance(llvm::Value* idxRaw, const std::string& hintAlias="") override;

private:
  ArrayIR __compiler;
};

}} // xreate::containers

#endif //XREATE_ARRAYSIR_H
