#ifndef _UNORDERED_SET_
#define _UNORDERED_SET_

#include <functional>
#include <initializer_list>
#include <memory>

namespace std {

template <typename T, typename Hash = hash<T>, typename Pred = equal_to<T>,
          typename Allocator = allocator<T>>
class unordered_set {
public:
  using value_type = T;
  using key_type = T;

  class iterator {
  public:
    iterator &operator++();
    iterator operator++(int);
    bool operator!=(const iterator &other) const;
    bool operator==(const iterator &other) const;
    const T &operator*() const;
    const T *operator->() const;
  };
  class const_iterator {
  public:
    const_iterator() = default;
    const_iterator(const iterator &) {}
    const_iterator &operator++();
    const_iterator operator++(int);
    bool operator!=(const const_iterator &other) const;
    bool operator==(const const_iterator &other) const;
    const T &operator*() const;
    const T *operator->() const;
  };

  unordered_set() = default;
  unordered_set(initializer_list<T>) {}

  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

  template <typename... Args>
  void emplace(Args &&...args) {}
  template <typename... Args>
  iterator emplace_hint(const_iterator pos, Args &&...args);

  iterator find(const T &);
  const_iterator find(const T &) const;

  unsigned count(const T &) const;
  bool contains(const T &) const;

  void clear();
  bool empty() const;
  size_t size() const;
};

template <typename T, typename Hash = hash<T>, typename Pred = equal_to<T>,
          typename Allocator = allocator<T>>
class unordered_multiset {
public:
  using value_type = T;
  using key_type = T;

  class iterator {
  public:
    iterator &operator++();
    iterator operator++(int);
    bool operator!=(const iterator &other) const;
    bool operator==(const iterator &other) const;
    const T &operator*() const;
    const T *operator->() const;
  };
  class const_iterator {
  public:
    const_iterator() = default;
    const_iterator(const iterator &) {}
    const_iterator &operator++();
    const_iterator operator++(int);
    bool operator!=(const const_iterator &other) const;
    bool operator==(const const_iterator &other) const;
    const T &operator*() const;
    const T *operator->() const;
  };

  unordered_multiset() = default;
  unordered_multiset(initializer_list<T>) {}

  iterator begin();
  const_iterator begin() const;
  iterator end();
  const_iterator end() const;

  template <typename... Args>
  void emplace(Args &&...args) {}
  template <typename... Args>
  iterator emplace_hint(const_iterator pos, Args &&...args);

  unsigned count(const T &) const;
  bool contains(const T &) const;

  void clear();
  bool empty() const;
  size_t size() const;
};

} // namespace std

#endif // _UNORDERED_SET_
