#ifndef UTILITIES_H
#define UTILITIES_H


#include <tuple>
#include <utility> 


// This comes from here:
//   http://stackoverflow.com/questions/4988939/how-do-boostvariant-and-boostany-work
// Currently not using this, but it might be useful in the future and explains idea behine how boost::any works
struct f_any
{
  f_any() : ptr() {}
  ~f_any() { delete ptr; }
  bool valid() const { return ptr != 0; }
  void f() { assert(ptr); ptr->f(); }

  struct placeholder
  {
    virtual ~placeholder() {}
    virtual void f() const = 0;
  };

  template < typename T >
  struct impl : placeholder
  {
    impl(T const& t) : val(t) {}
    void f() const { val.f(); }
    T val;
  };
  // ptr can now point to the entire family of 
  // struct types generated from impl<T>
  placeholder * ptr;

  template < typename T >
  f_any(T const& t) : ptr(new impl<T>(t)) {}

  // assignment, etc...
};


// The idea comes from here:
//   http://stackoverflow.com/questions/1197106/static-constructors-in-c-need-to-initialize-private-static-objects
// Currently this isn't being used, but it is a neat solution and for some reason it was low in the
// voted for solutions. It appears quite low on the stackoverflow page. I actually quite like it.
// Usage:     static void StaticTest() {
//              static_constructor<&Test::StaticTest>::c;
//              // <insert code you actually want to run once at startup here>
//            }
template<void(*ctor)()>
struct static_constructor
{
  struct constructor { constructor() { ctor(); } };
  static constructor c;
};
template<void(*ctor)()>
typename static_constructor<ctor>::constructor static_constructor<ctor>::c;



// The idea behind this comes from here:
//    http://stackoverflow.com/questions/1198260/iterate-over-tuple
template<typename V, typename T, std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
for_each(V& v, T obj, std::tuple<Tp...> &) // Unused arguments are given no names.
{ }

template<typename V, typename T, std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
for_each(V& v, T obj, std::tuple<Tp...>& t)
{
  v.Visit(std::get<I>(t), std::get<I+1>(t)(obj));
  for_each<V, T, I + 2, Tp...>(v, obj, t);
}


#endif // UTILITIES_H

