<commit_before>#pragma once
#include "Archive.h"
#include "field_serializer.h"
#include "serial_traits.h"
#include <mutex>
#include <unordered_map>

namespace leap {
  template<typename T, typename = void>
  struct field_serializer_t {
    static_assert(std::is_same<T, void>::value, "An attempt was made to serialize type T, which does not provide a serial_traits entry or GetDescriptor function");
  };

  template<typename T>
  struct serial_traits;

  // Objects that provide serial_traits should use those traits externally
  template<typename T>
  struct field_serializer_t<T, typename std::enable_if<!std::is_base_of<std::false_type, serial_traits<T>>::value>::type> :
    field_serializer
  {
    bool allocates(void) const override {
      return serializer_is_irresponsible<T>::value;
    }

    serial_atom type(void) const override {
      return serial_traits<T>::type();
    }

    uint64_t size(const OArchiveRegistry& ar, const void* pObj) const override {
      return serial_traits<T>::size(ar, *static_cast<const T*>(pObj));
    }

    void serialize(OArchiveRegistry& ar, const void* pObj) const override {
      serial_traits<T>::serialize(ar, *static_cast<const T*>(pObj));
    }

    void deserialize(IArchiveRegistry& ar, void* pObj, uint64_t ncb) const override {
      serial_traits<T>::deserialize(ar, *static_cast<T*>(pObj), ncb);
    }

    static const field_serializer& GetDescriptor(void) {
      static const field_serializer_t m{};
      return m;
    }
  };

  template<typename T>
  struct field_serializer_t<void(T::*)()>:
    field_serializer
  {
    void(T::*pfn)();

    bool allocates(void) const override { return false; }

    serial_atom type(void) const override {
      return serial_atom::ignored;
    }

    uint64_t size(const OArchiveRegistry& ar, const void* pObj) const override {
      return 0;
    }

    void serialize(OArchiveRegistry& ar, const void* pObj) const override {
      // Does nothing
    }

    void deserialize(IArchiveRegistry& ar, void* pObj, uint64_t ncb) const override {
      (static_cast<T*>(pObj)->*pfn)();
    }

    struct hash {
      size_t operator()(void(T::*pfn)()) const {
        return *reinterpret_cast<size_t*>(&pfn);
      }
    };

    static const field_serializer& GetDescriptor(void(T::*pfn)()) {
      static std::unordered_map<void(T::*)(), field_serializer_t, hash> mp;
      static std::mutex lock;

      std::lock_guard<std::mutex> lk(lock);
      auto& entry = mp[pfn];
      entry.pfn = pfn;
      return entry;
    }
  };
}<commit_msg>Switch from maps to sets<commit_after>#pragma once
#include "Archive.h"
#include "field_serializer.h"
#include "serial_traits.h"
#include <mutex>
#include <unordered_set>

namespace leap {
  template<typename T, typename = void>
  struct field_serializer_t {
    static_assert(std::is_same<T, void>::value, "An attempt was made to serialize type T, which does not provide a serial_traits entry or GetDescriptor function");
  };

  template<typename T>
  struct serial_traits;

  // Objects that provide serial_traits should use those traits externally
  template<typename T>
  struct field_serializer_t<T, typename std::enable_if<!std::is_base_of<std::false_type, serial_traits<T>>::value>::type> :
    field_serializer
  {
    bool allocates(void) const override {
      return serializer_is_irresponsible<T>::value;
    }

    serial_atom type(void) const override {
      return serial_traits<T>::type();
    }

    uint64_t size(const OArchiveRegistry& ar, const void* pObj) const override {
      return serial_traits<T>::size(ar, *static_cast<const T*>(pObj));
    }

    void serialize(OArchiveRegistry& ar, const void* pObj) const override {
      serial_traits<T>::serialize(ar, *static_cast<const T*>(pObj));
    }

    void deserialize(IArchiveRegistry& ar, void* pObj, uint64_t ncb) const override {
      serial_traits<T>::deserialize(ar, *static_cast<T*>(pObj), ncb);
    }

    static const field_serializer& GetDescriptor(void) {
      static const field_serializer_t m{};
      return m;
    }
  };

  template<typename T>
  struct mem_hash {
    size_t operator()(const T& obj) const {
      size_t retVal = 0;
      for (size_t i = 0; i < sizeof(obj); i++)
        retVal += retVal * 101 + reinterpret_cast<const char*>(&obj)[i];
      return retVal;
    }
  };

  template<typename T>
  struct field_serializer_t<void(T::*)()>:
    field_serializer
  {
    field_serializer_t(void(T::*pfn)()):
      pfn(pfn)
    {}

    void(T::*pfn)();

    bool allocates(void) const override { return false; }

    serial_atom type(void) const override {
      return serial_atom::ignored;
    }

    uint64_t size(const OArchiveRegistry& ar, const void* pObj) const override {
      return 0;
    }

    void serialize(OArchiveRegistry& ar, const void* pObj) const override {
      // Does nothing
    }

    void deserialize(IArchiveRegistry& ar, void* pObj, uint64_t ncb) const override {
      (static_cast<T*>(pObj)->*pfn)();
    }

    bool operator==(const field_serializer_t& rhs) const {
      return pfn == rhs.pfn;
    }

    static const field_serializer& GetDescriptor(void(T::*pfn)()) {
      static std::unordered_set<field_serializer_t, mem_hash<field_serializer_t>> st;
      static std::mutex lock;

      std::lock_guard<std::mutex> lk(lock);
      field_serializer_t key{pfn};
      auto q = st.find(key);
      if (q == st.end())
        q = st.insert(q, key);
      return *q;
    }
  };
}
{'fraction_non_alphanumeric': 0.12403810919750824, 'fraction_numerical': 0.004213997801392451, 'mean_word_length': 3.677806341045416, 'pattern_counts': {'":': 0, '<': 54, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4292005', 'n_tokens_mistral': 1841, 'n_tokens_neox': 1761, 'n_words': 430}