Framework — spec

#include <type_traits>
#include <cstddef>
#include <vector>
#include <utility>
#include <memory>
#include <boost/optional.hpp>


namespace framework
{  
  template <typename T>
  struct mem_usage3
  {
    static_assert(std::is_trivial<T>::value, "specialize");
    static size_t get(const T& v) { return sizeof v; }
  };
  
  template <typename T>
  size_t mem_usage(const T& v)
  {
    return mem_usage3<T>::get(v);
  }
}

namespace framework
{
  namespace algo
  {
    template <typename T>
    size_t score(const T& v)
    {
      // do some more things
      return mem_usage(v);
    }
  }
}

namespace framework
{
  template <typename T>
  class Array
  {
    std::unique_ptr<T[]> ptr_;
    size_t size_;
    
  public:
    explicit Array(size_t s) : ptr_(new T [s]), size_(s) {}
    T const* begin() const { return &ptr_[0]; }
    T const* end() const { return &ptr_[size_]; }
  };
  
  template <typename T>
  struct mem_usage3< Array<T> >
  {
    static size_t get(const Array<T>& v)
    {
      size_t ans = sizeof(v);
      for (const T& e : v)
        ans += mem_usage3<T>::get(e);
      return ans;
    }
  };
  

}

namespace framework
{
  template <typename T>
  struct mem_usage3< std::vector<T> >
  {
    static size_t get(const std::vector<T>& v)
    { 
      size_t ans = sizeof(v);
      for (const T& e : v) ans += mem_usage3<T>::get(e);
      ans += (v.capacity() - v.size()) * sizeof(T);
      return ans;
    }
  };
  
  template <typename T, typename U>
  struct mem_usage3< std::pair<T, U> >
  {
    static size_t get(const std::pair<T, U>& v)
    { 
      return mem_usage3<T>::get(v.first)
           + mem_usage3<U>::get(v.second);
    }
  };

}

namespace framework
{
  template <typename T>
  struct mem_usage3< boost::optional<T> >
  {
    static size_t get(const boost::optional<T>& v)
    {
      size_t ans = sizeof(v);
      if (v) ans += mem_usage3<T>::get(*v) - sizeof(*v);
      return ans;
    }
  };
}

int main()
{
  int i = 0;
  framework::Array<int> a (10);
  std::vector<int> v (10);
  std::vector<std::pair<int, int>> vp;
  boost::optional<int> o;
  
  framework::algo::score(i);
  framework::algo::score(a);
  framework::algo::score(v);
  framework::algo::score(o);
  framework::algo::score(vp);
}
Advertisements