/*
 Do not modify, auto-generated by classes.py

 Copyright 2019 Alain Dargelas

 Licensed 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.
 */

/*
 * File:   task_func.h
 * Author:
 *
 * Created on December 14, 2019, 10:03 PM
 */

#ifndef UHDM_TASK_FUNC_H
#define UHDM_TASK_FUNC_H

#include <uhdm/sv_vpi_user.h>
#include <uhdm/uhdm_vpi_user.h>

#include <uhdm/containers.h>
#include <uhdm/scope.h>

#include "stmt.h"


namespace UHDM {
class clocking_block;
class expr;
class instance;
class variables;

class task_func : public scope {
  UHDM_IMPLEMENT_RTTI(task_func, scope)
public:
  // Implicit constructor used to initialize all members,
  // comment: task_func();
  virtual ~task_func() = default;

  bool VpiMethod() const { return vpiMethod_; }
  bool VpiMethod(bool data) {
    vpiMethod_ = data;
    return true;
  }

  int32_t VpiAccessType() const { return vpiAccessType_; }
  bool VpiAccessType(int32_t data) {
    vpiAccessType_ = data;
    return true;
  }

  int32_t VpiVisibility() const { return vpiVisibility_; }
  bool VpiVisibility(int32_t data) {
    vpiVisibility_ = data;
    return true;
  }

  bool VpiVirtual() const { return vpiVirtual_; }
  bool VpiVirtual(bool data) {
    vpiVirtual_ = data;
    return true;
  }

  bool VpiAutomatic() const { return vpiAutomatic_; }
  bool VpiAutomatic(bool data) {
    vpiAutomatic_ = data;
    return true;
  }

  bool VpiDPIPure() const { return vpiDPIPure_; }
  bool VpiDPIPure(bool data) {
    vpiDPIPure_ = data;
    return true;
  }

  bool VpiDPIContext() const { return vpiDPIContext_; }
  bool VpiDPIContext(bool data) {
    vpiDPIContext_ = data;
    return true;
  }

  int32_t VpiDPICStr() const { return vpiDPICStr_; }
  bool VpiDPICStr(int32_t data) {
    vpiDPICStr_ = data;
    return true;
  }

  bool VpiDPICIdentifier(std::string_view data);
  std::string_view VpiDPICIdentifier() const;

  expr* Left_range()  { return left_range_; }
  const expr* Left_range() const { return left_range_; }
  template <typename T>
  T* Left_range() {
    return (left_range_ == nullptr) ? nullptr : any_cast<T*>(left_range_);
  }
  template <typename T>
  const T* Left_range() const {
    return (left_range_ == nullptr) ? nullptr : any_cast<const T*>(left_range_);
  }
  bool Left_range(expr* data) {
    left_range_ = data;
    return true;
  }

  expr* Right_range()  { return right_range_; }
  const expr* Right_range() const { return right_range_; }
  template <typename T>
  T* Right_range() {
    return (right_range_ == nullptr) ? nullptr : any_cast<T*>(right_range_);
  }
  template <typename T>
  const T* Right_range() const {
    return (right_range_ == nullptr) ? nullptr : any_cast<const T*>(right_range_);
  }
  bool Right_range(expr* data) {
    right_range_ = data;
    return true;
  }

  variables* Return()  { return return_; }
  const variables* Return() const { return return_; }
  template <typename T>
  T* Return() {
    return (return_ == nullptr) ? nullptr : any_cast<T*>(return_);
  }
  template <typename T>
  const T* Return() const {
    return (return_ == nullptr) ? nullptr : any_cast<const T*>(return_);
  }
  bool Return(variables* data) {
    return_ = data;
    return true;
  }

  clocking_block* Class_defn()  { return class_defn_; }
  const clocking_block* Class_defn() const { return class_defn_; }
  template <typename T>
  T* Class_defn() {
    return (class_defn_ == nullptr) ? nullptr : any_cast<T*>(class_defn_);
  }
  template <typename T>
  const T* Class_defn() const {
    return (class_defn_ == nullptr) ? nullptr : any_cast<const T*>(class_defn_);
  }
  bool Class_defn(clocking_block* data) {
    class_defn_ = data;
    return true;
  }

  VectorOfio_decl* Io_decls() const { return io_decls_; }
  bool Io_decls(VectorOfio_decl* data) {
    io_decls_ = data;
    return true;
  }

  any* Stmt()  { return stmt_; }
  const any* Stmt() const { return stmt_; }
  template <typename T>
  T* Stmt() {
    return (stmt_ == nullptr) ? nullptr : any_cast<T*>(stmt_);
  }
  template <typename T>
  const T* Stmt() const {
    return (stmt_ == nullptr) ? nullptr : any_cast<const T*>(stmt_);
  }
  bool Stmt(any* data) {
    if (!stmtGroupCompliant(data)) return false;
    stmt_ = data;
    return true;
  }

  instance* Instance()  { return instance_; }
  const instance* Instance() const { return instance_; }
  template <typename T>
  T* Instance() {
    return (instance_ == nullptr) ? nullptr : any_cast<T*>(instance_);
  }
  template <typename T>
  const T* Instance() const {
    return (instance_ == nullptr) ? nullptr : any_cast<const T*>(instance_);
  }
  bool Instance(instance* data) {
    instance_ = data;
    return true;
  }

  virtual task_func* DeepClone(BaseClass* parent, CloneContext* context) const override = 0;

  virtual const BaseClass* GetByVpiName(std::string_view name) const override;

  virtual std::tuple<const BaseClass*, UHDM_OBJECT_TYPE, const std::vector<const BaseClass*>*> GetByVpiType(int32_t type) const override;

  virtual vpi_property_value_t GetVpiPropertyValue(int32_t property) const override;

  virtual int32_t Compare(const BaseClass* other, CompareContext* context) const override;

  virtual  UHDM_OBJECT_TYPE UhdmType() const override { return UHDM_OBJECT_TYPE::uhdmtask_func; }

protected:
  void DeepCopy(task_func* clone, BaseClass* parent, CloneContext* context) const;

private:
  bool vpiMethod_ = false;

  int32_t vpiAccessType_ = 0;

  int32_t vpiVisibility_ = 0;

  bool vpiVirtual_ = false;

  bool vpiAutomatic_ = false;

  bool vpiDPIPure_ = false;

  bool vpiDPIContext_ = false;

  int32_t vpiDPICStr_ = 0;

  SymbolId vpiDPICIdentifier_;

  expr* left_range_ = nullptr;

  expr* right_range_ = nullptr;

  variables* return_ = nullptr;

  clocking_block* class_defn_ = nullptr;

  VectorOfio_decl* io_decls_ = nullptr;

  any* stmt_ = nullptr;

  instance* instance_ = nullptr;
};

#if 0 // This class cannot be instantiated
typedef FactoryT<task_func> task_funcFactory;
#endif

typedef FactoryT<std::vector<task_func *>> VectorOftask_funcFactory;

}  // namespace UHDM

#endif
