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,
|
explicit scoped_map(size_type bucket_count = LEAN_SCOPED_MAP_INITIAL_BUCKET_SIZE,
|
||||||
const Hash& hash = Hash(),
|
const Hash& hash = Hash(),
|
||||||
const KeyEqual& equal = KeyEqual()):
|
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) {
|
void swap(scoped_map & other) {
|
||||||
m_map.swap(other.m_map);
|
m_map.swap(other.m_map);
|
||||||
|
|
|
@ -31,7 +31,16 @@ public:
|
||||||
explicit scoped_set(size_type bucket_count = LEAN_SCOPED_SET_INITIAL_BUCKET_SIZE,
|
explicit scoped_set(size_type bucket_count = LEAN_SCOPED_SET_INITIAL_BUCKET_SIZE,
|
||||||
const Hash& hash = Hash(),
|
const Hash& hash = Hash(),
|
||||||
const KeyEqual& equal = KeyEqual()):
|
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. */
|
/** \brief Return the number of scopes. */
|
||||||
unsigned num_scopes() const {
|
unsigned num_scopes() const {
|
||||||
|
|
|
@ -22,8 +22,12 @@ class splay_map : public CMP {
|
||||||
};
|
};
|
||||||
splay_tree<entry, entry_cmp> m_map;
|
splay_tree<entry, entry_cmp> m_map;
|
||||||
public:
|
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); }
|
void swap(splay_map & m) { m_map.swap(m.m_map); }
|
||||||
bool empty() const { return m_map.empty(); }
|
bool empty() const { return m_map.empty(); }
|
||||||
void clear() { m_map.clear(); }
|
void clear() { m_map.clear(); }
|
||||||
|
@ -60,12 +64,16 @@ public:
|
||||||
|
|
||||||
template<typename F, typename R>
|
template<typename F, typename R>
|
||||||
R fold(F f, R r) const {
|
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); };
|
auto f_prime = [&](entry const & e, R r) -> R { return f(e.first, e.second, r); };
|
||||||
return m_map.fold(f_prime, r);
|
return m_map.fold(f_prime, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void for_each(F f) const {
|
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); };
|
auto f_prime = [&](entry const & e) { f(e.first, e.second); };
|
||||||
return m_map.for_each(f_prime);
|
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>
|
template<typename K, typename T, typename CMP, typename F, typename R>
|
||||||
R fold(splay_map<K, T, CMP> const & m, F f, R 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);
|
return m.fold(f, r);
|
||||||
}
|
}
|
||||||
template<typename K, typename T, typename CMP, typename F>
|
template<typename K, typename T, typename CMP, typename F>
|
||||||
void for_each(splay_map<K, T, CMP> const & m, F 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);
|
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(); }
|
static void dec_ref(node * n) { if (n) n->dec_ref(); }
|
||||||
explicit node(T const & v, node * left = nullptr, node * right = nullptr):
|
explicit node(T const & v, node * left = nullptr, node * right = nullptr):
|
||||||
m_left(left), m_right(right), m_value(v), m_rc(0) {
|
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_left);
|
||||||
inc_ref(m_right);
|
inc_ref(m_right);
|
||||||
}
|
}
|
||||||
|
@ -289,6 +293,8 @@ class splay_tree : public CMP {
|
||||||
|
|
||||||
template<typename F, typename R>
|
template<typename F, typename R>
|
||||||
static R fold(node const * n, F & f, R 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) {
|
if (n) {
|
||||||
r = fold(n->m_left, f, r);
|
r = fold(n->m_left, f, r);
|
||||||
r = f(n->m_value, r);
|
r = f(n->m_value, r);
|
||||||
|
@ -300,6 +306,8 @@ class splay_tree : public CMP {
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
static void for_each(node const * n, F & 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) {
|
if (n) {
|
||||||
for_each(n->m_left, f);
|
for_each(n->m_left, f);
|
||||||
f(n->m_value);
|
f(n->m_value);
|
||||||
|
@ -332,7 +340,7 @@ public:
|
||||||
bool is_eqp(splay_tree const & t) const { return m_ptr == t.m_ptr; }
|
bool is_eqp(splay_tree const & t) const { return m_ptr == t.m_ptr; }
|
||||||
|
|
||||||
/** \brief Return the size of the splay tree */
|
/** \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. */
|
/** \brief Insert \c v in this splay tree. */
|
||||||
void insert(T const & v) {
|
void insert(T const & v) {
|
||||||
|
@ -425,6 +433,8 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename F, typename R>
|
template<typename F, typename R>
|
||||||
R fold(F f, R r) const {
|
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);
|
return fold(m_ptr, f, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -433,6 +443,8 @@ public:
|
||||||
*/
|
*/
|
||||||
template<typename F>
|
template<typename F>
|
||||||
void for_each(F f) const {
|
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);
|
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; }
|
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>
|
template<typename T, typename CMP, typename F, typename R>
|
||||||
R fold(splay_tree<T, CMP> const & t, F f, R 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);
|
return t.fold(f, r);
|
||||||
}
|
}
|
||||||
template<typename T, typename CMP, typename F>
|
template<typename T, typename CMP, typename F>
|
||||||
void for_each(splay_tree<T, CMP> const & t, F 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);
|
return t.for_each(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue