/*******************************************************************************
 *
 * File:     SystemImpl.hpp
 *
 * Contents: Declaration of a basic implementation of the System interface.
 *
 * Copyright 2017
 *
 * Author: David Juhasz (david.juhasz@tuwien.ac.at)
 *
 ******************************************************************************/

#ifndef ROSA_LIB_CORE_SYSTEMIMPL_HPP // NOLINT
#define ROSA_LIB_CORE_SYSTEMIMPL_HPP

#include "rosa/core/SystemBase.hpp"

#include <mutex>
#include <unordered_set>

namespace rosa {

// A basic implementation of the System interface, which simply stores Units in
// a set.
class SystemImpl : public SystemBase {
public:
  // Ctor.
  SystemImpl(const std::string &Name) noexcept;

  // Dtor.
  // PRE: empty()
  ~SystemImpl(void);

private:
  // Container for keeping reference of registered Units.
  std::unordered_set<Unit *> Units;

  // Used to provide mutual exclusion when modifying Units.
  std::mutex RegisterMutex;

protected:
  // Registers the given Unit instance to the System.
  // PRE: !isUnitRegistered(U)
  // POST: isUnitRegistered(U)
  void registerUnit(Unit &U) noexcept override;

  // Unregisters and destroys the given Unit.
  // PRE: isUnitRegistered(U)
  // POST: !isUnitRegistered(U) && 'U is destroyed'
  void destroyUnit(Unit &U) noexcept override;

  // Returns if the given Unit is registered in the System.
  bool isUnitRegistered(const Unit &U) const noexcept override;

public:
  // Returns the number of live Units, that have been constructed and not
  // destroyed yet.
  size_t numberOfLiveUnits(void) const noexcept override;

  // Returns if the System has no live Units.
  bool empty(void) const noexcept override;
};

} // End namespace rosa

#endif // ROSA_LIB_CORE_SYSTEMIMPL_HPP

