feat(util): add static_assert to {scoped,splay}_{map,set}

This commit is contained in:
Soonho Kong 2013-10-01 16:06:44 -07:00
parent a726f5fbb7
commit b823c7d779
4 changed files with 51 additions and 5 deletions

View file

@ -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);

View file

@ -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 {

View file

@ -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);
}
}

View file

@ -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);
}
}