/*
   Copyright (C) 2004 - 2013 by Guillaume Melquiond <guillaume.melquiond@inria.fr>
   Part of the Gappa tool https://gappa.gitlabpages.inria.fr/

   This program is free software; you can redistribute it and/or modify
   it under the terms of the CeCILL Free Software License Agreement or
   under the terms of the GNU General Public License version.

   See the COPYING and COPYING.GPL files for more details.
*/

#ifndef UTILS_HPP
#define UTILS_HPP

extern bool enable_debug;

#define RUN_ONCE(name) \
  struct class_##name { class_##name(); }; \
  static class_##name dummy_##name; \
  class_##name::class_##name()

#define WARNING(s) \
  do { std::cerr << "[WARNING] " << s << '\n'; } while (0)

#define ERROR(s) \
  do { std::cerr << "[ERROR] " << s << '\n'; } while (0)

#define DEBUG(s) \
  do { if (enable_debug) std::cerr << "[DEBUG] " << s << '\n'; } while (0)

#ifdef LEAK_CHECKER

#define RUN_LAST(name) \
  struct class_##name { ~class_##name(); }; \
  static class_##name dummy_##name; \
  class_##name::~class_##name()

#else

#define RUN_LAST(name) \
  __attribute__((unused)) \
  static void dummy_##name()

#endif

template<class T>
class static_ptr
{
  T *ptr;
 public:
  ~static_ptr() { delete ptr; }
  T *operator->() { if (!ptr) ptr = new T; return ptr; }
  T &operator*() { if (!ptr) ptr = new T; return *ptr; }
};

#endif // UTILS_HPP
