//===-- support/atom.cpp ----------------------------------------*- C++ -*-===//
//
//                                 The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file support/atom.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of non-static part of atom facilities of
///        rosa/support/atom.hpp.
///
/// \note This implementation is based on the `atom` implementation of CAF.
/// \todo Check license.
///
//===----------------------------------------------------------------------===//

#include "rosa/support/atom.hpp"

namespace rosa {

AtomValue atom_from_string(const std::string &S) {
  if (S.size() > MaxAtomLength) {
    return atom("");
  }
  char AtomBuf[MaxAtomLength + 1];
  std::memcpy(AtomBuf, S.c_str(), S.size());
  AtomBuf[S.size()] = '\0';
  return atom(AtomBuf);
}

} // End namespace rosa

namespace std {

string to_string(const rosa::AtomValue &What) {
  auto X = static_cast<rosa::atom_t>(What);
  string S;
  S.reserve(rosa::MaxAtomLength + 1);
  // Don't read characters before we found the leading 0xF.
  // First four bits set?
  bool ReadChars = ((X & 0xF000000000000000) >> 60) == 0xF;
  uint64_t Mask = 0x0FC0000000000000;
  for (int BitShift = 54; BitShift >= 0; BitShift -= 6, Mask >>= 6) {
    if (ReadChars) {
      S += rosa::AtomDecodingTable[(X & Mask) >> BitShift];
    } else if (((X & Mask) >> BitShift) == 0xF) {
      ReadChars = true;
    }
  }
  return S;
}

} // End namespace std
