Program Listing for File format.h

Return to documentation for file (src/sparsebase/format/format.h)

/*******************************************************
 * Copyright (c) 2022 SparCity, Amro Alabsi Aljundi, Taha Atahan Akyildiz, Arda
 *Sener All rights reserved.
 *
 * This file is distributed under MIT license.
 * The complete license agreement can be obtained at:
 * https://sparcityeu.github.io/sparsebase/pages/license.html
 ********************************************************/
#ifndef SPARSEBASE_SPARSEBASE_FORMAT_FORMAT_H_
#define SPARSEBASE_SPARSEBASE_FORMAT_FORMAT_H_

#include <cxxabi.h>

#include <algorithm>
#include <cstring>
#include <fstream>
#include <functional>
#include <memory>
#include <typeindex>
#include <typeinfo>
#include <vector>

#include "sparsebase/config.h"
#include "sparsebase/context/context.h"
#include "sparsebase/utils/exception.h"
#include "sparsebase/utils/utils.h"

namespace sparsebase {

namespace converter {
class Converter;
template <typename ValueType>
class ConverterOrderOne;
template <typename IDType, typename NNZType, typename ValueType>
class ConverterOrderTwo;
}  // namespace converter

namespace format {

enum Ownership {
  kNotOwned = 0,
  kOwned = 1,
};

template <typename T>
struct Deleter {
  void operator()(T *obj) {
    if constexpr (!std::is_same_v<T, void>)
      if (obj != nullptr) delete obj;
  }
};

template <long long dim, typename T>
struct Deleter2D {
  void operator()(T *obj) {
    for (long long i = 0; i < dim; i++) {
      delete[] obj[i];
    }
    delete[] obj;
  }
};

template <class T>
struct BlankDeleter {
  void operator()(T *obj) {}
};

typedef unsigned long long DimensionType;


class Format : public utils::Identifiable {
 public:

  // virtual std::type_index get_id() = 0;

  // virtual std::string get_name() = 0;

  virtual ~Format() = default;

  virtual Format *Clone() const = 0;

  virtual std::vector<DimensionType> get_dimensions() const = 0;

  virtual DimensionType get_num_nnz() const = 0;

  virtual DimensionType get_order() const = 0;

  virtual context::Context *get_context() const = 0;

  virtual std::type_index get_id() const = 0;

  virtual std::shared_ptr<converter::Converter const> get_converter() const = 0;

  // virtual void set_converter(converter::Converter*) = 0;


  template <typename T>
  typename std::remove_pointer<T>::type *AsAbsolute() {
    static_assert(std::is_base_of_v<Format, T>,
                  "Cannot cast a non-Format class using AsAbsolute");
    using TBase = typename std::remove_pointer<T>::type;
    if (this->get_id() == std::type_index(typeid(TBase))) {
      return static_cast<TBase *>(this);
    }
    throw utils::TypeException(get_name(), typeid(TBase).name());
  }
  template <template <typename...> typename T>
  void *AsAbsolute() {
    static_assert(utils::always_false<T<void>>,
                  "When casting a format pointer, you need to pass the data "
                  "type with the template arguments");
    return nullptr;
  }


  template <typename T>
  bool IsAbsolute() {
    using Tbase = typename std::remove_pointer<T>::type;
    return this->get_id() == std::type_index(typeid(Tbase));
}
};

}  // namespace format

}  // namespace sparsebase
#endif