feat(util): add static_assert to {scoped,splay}_{map,set}
This commit is contained in:
parent
a726f5fbb7
commit
b823c7d779
4 changed files with 51 additions and 5 deletions
|
@ -33,7 +33,16 @@ public:
|
|||
explicit scoped_map(size_type bucket_count = LEAN_SCOPED_MAP_INITIAL_BUCKET_SIZE,
|
||||
const Hash& hash = Hash(),
|
||||
const KeyEqual& equal = KeyEqual()):
|
||||
m_map(bucket_count, hash, equal) {}
|
||||
m_map(bucket_count, hash, equal) {
|
||||
// the return type of Hash()(k) should be convertible to size_t
|
||||
static_assert(std::is_convertible<typename std::result_of<decltype(std::declval<Hash>())(Key const &)>::type,
|
||||
std::size_t>::value,
|
||||
"The return type of hash function is not convertible to std::size_t");
|
||||
// the return type of KeyEqual()(k1, k2) should be bool
|
||||
static_assert(std::is_same<typename std::result_of<decltype(std::declval<KeyEqual>())(Key const &, Key const &)>::type,
|
||||
bool>::value,
|
||||
"The return type of KeyEqual()(k1, k2) is not bool");
|
||||
}
|
||||
|
||||
void swap(scoped_map & other) {
|
||||
m_map.swap(other.m_map);
|
||||
|
|
|
@ -31,7 +31,16 @@ public:
|
|||
explicit scoped_set(size_type bucket_count = LEAN_SCOPED_SET_INITIAL_BUCKET_SIZE,
|
||||
const Hash& hash = Hash(),
|
||||
const KeyEqual& equal = KeyEqual()):
|
||||
m_set(bucket_count, hash, equal) {}
|
||||
m_set(bucket_count, hash, equal) {
|
||||
// the return type of Hash()(k) should be convertible to size_t
|
||||
static_assert(std::is_convertible<typename std::result_of<decltype(std::declval<Hash>())(Key const &)>::type,
|
||||
std::size_t>::value,
|
||||
"The return type of hash function is not convertible to std::size_t");
|
||||
// the return type of KeyEqual()(k1, k2) should be bool
|
||||
static_assert(std::is_same<typename std::result_of<decltype(std::declval<KeyEqual>())(Key const &, Key const &)>::type,
|
||||
bool>::value,
|
||||
"The return type of KeyEqual()(k1, k2) is not bool");
|
||||
}
|
||||
|
||||
/** \brief Return the number of scopes. */
|
||||
unsigned num_scopes() const {
|
||||
|
|
|
@ -22,8 +22,12 @@ class splay_map : public CMP {
|
|||
};
|
||||
splay_tree<entry, entry_cmp> m_map;
|
||||
public:
|
||||
splay_map(CMP const & cmp = CMP()):m_map(entry_cmp(cmp)) {}
|
||||
|
||||
splay_map(CMP const & cmp = CMP()):m_map(entry_cmp(cmp)) {
|
||||
// the return type of CMP()(k1, k2) should be int
|
||||
static_assert(std::is_same<typename std::result_of<decltype(std::declval<CMP>())(K const &, K const &)>::type,
|
||||
int>::value,
|
||||
"The return type of CMP()(k1, k2) is not int.");
|
||||
}
|
||||
void swap(splay_map & m) { m_map.swap(m.m_map); }
|
||||
bool empty() const { return m_map.empty(); }
|
||||
void clear() { m_map.clear(); }
|
||||
|
@ -60,12 +64,16 @@ public:
|
|||
|
||||
template<typename F, typename R>
|
||||
R fold(F f, R r) const {
|
||||
static_assert(std::is_same<typename std::result_of<F(K const &, T const &, R const &)>::type, R>::value,
|
||||
"fold: return type of f(k : K, t : T, r : R) is not R");
|
||||
auto f_prime = [&](entry const & e, R r) -> R { return f(e.first, e.second, r); };
|
||||
return m_map.fold(f_prime, r);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void for_each(F f) const {
|
||||
static_assert(std::is_same<typename std::result_of<F(K const &, T const &)>::type, void>::value,
|
||||
"for_each: return type of f is not void");
|
||||
auto f_prime = [&](entry const & e) { f(e.first, e.second); };
|
||||
return m_map.for_each(f_prime);
|
||||
}
|
||||
|
@ -94,10 +102,14 @@ splay_map<K, T, CMP> erase(splay_map<K, T, CMP> const & m, K const & k) {
|
|||
}
|
||||
template<typename K, typename T, typename CMP, typename F, typename R>
|
||||
R fold(splay_map<K, T, CMP> const & m, F f, R r) {
|
||||
static_assert(std::is_same<typename std::result_of<F(K const &, T const &, R const &)>::type, R>::value,
|
||||
"fold: return type of f(k : K, t : T, r : R) is not R");
|
||||
return m.fold(f, r);
|
||||
}
|
||||
template<typename K, typename T, typename CMP, typename F>
|
||||
void for_each(splay_map<K, T, CMP> const & m, F f) {
|
||||
static_assert(std::is_same<typename std::result_of<F(K const &, T const &)>::type, void>::value,
|
||||
"for_each: return type of f is not void");
|
||||
return m.for_each(f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ class splay_tree : public CMP {
|
|||
static void dec_ref(node * n) { if (n) n->dec_ref(); }
|
||||
explicit node(T const & v, node * left = nullptr, node * right = nullptr):
|
||||
m_left(left), m_right(right), m_value(v), m_rc(0) {
|
||||
// the return type of CMP()(t1, 2) should be int
|
||||
static_assert(std::is_same<typename std::result_of<decltype(std::declval<CMP>())(T const &, T const &)>::type,
|
||||
int>::value,
|
||||
"The return type of CMP()(t1, t2) is not int.");
|
||||
inc_ref(m_left);
|
||||
inc_ref(m_right);
|
||||
}
|
||||
|
@ -289,6 +293,8 @@ class splay_tree : public CMP {
|
|||
|
||||
template<typename F, typename R>
|
||||
static R fold(node const * n, F & f, R r) {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &, R)>::type, R>::value,
|
||||
"fold: return type of f(t : T, r : R) is not R");
|
||||
if (n) {
|
||||
r = fold(n->m_left, f, r);
|
||||
r = f(n->m_value, r);
|
||||
|
@ -300,6 +306,8 @@ class splay_tree : public CMP {
|
|||
|
||||
template<typename F>
|
||||
static void for_each(node const * n, F & f) {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &)>::type, void>::value,
|
||||
"for_each: return type of f is not void");
|
||||
if (n) {
|
||||
for_each(n->m_left, f);
|
||||
f(n->m_value);
|
||||
|
@ -332,7 +340,7 @@ public:
|
|||
bool is_eqp(splay_tree const & t) const { return m_ptr == t.m_ptr; }
|
||||
|
||||
/** \brief Return the size of the splay tree */
|
||||
unsigned size() const { return fold([](T const &, unsigned a) { return a + 1; }, 0); }
|
||||
unsigned size() const { return fold([](T const &, unsigned a) { return a + 1; }, 0u); }
|
||||
|
||||
/** \brief Insert \c v in this splay tree. */
|
||||
void insert(T const & v) {
|
||||
|
@ -425,6 +433,8 @@ public:
|
|||
*/
|
||||
template<typename F, typename R>
|
||||
R fold(F f, R r) const {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &, R)>::type, R>::value,
|
||||
"fold: return type of f(t : T, r : R) is not R");
|
||||
return fold(m_ptr, f, r);
|
||||
}
|
||||
|
||||
|
@ -433,6 +443,8 @@ public:
|
|||
*/
|
||||
template<typename F>
|
||||
void for_each(F f) const {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &)>::type, void>::value,
|
||||
"for_each: return type of f is not void");
|
||||
for_each(m_ptr, f);
|
||||
}
|
||||
};
|
||||
|
@ -442,10 +454,14 @@ template<typename T, typename CMP>
|
|||
splay_tree<T, CMP> erase(splay_tree<T, CMP> & t, T const & v) { splay_tree<T, CMP> r(t); r.erase(v); return r; }
|
||||
template<typename T, typename CMP, typename F, typename R>
|
||||
R fold(splay_tree<T, CMP> const & t, F f, R r) {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &, R)>::type, R>::value,
|
||||
"fold: return type of f(t : T, r : R) is not R");
|
||||
return t.fold(f, r);
|
||||
}
|
||||
template<typename T, typename CMP, typename F>
|
||||
void for_each(splay_tree<T, CMP> const & t, F f) {
|
||||
static_assert(std::is_same<typename std::result_of<F(T const &)>::type, void>::value,
|
||||
"for_each: return type of f is not void");
|
||||
return t.for_each(f);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue