*@{
*/
-// Forward declaration
-#ifndef DOXYGEN
-template <typename>
-class BlockVectorBase;
-#endif
+namespace internal
+{
+ template <typename T>
+ using has_block_t = decltype(std::declval<T const>().block(0));
+
+ template <typename T>
+ constexpr bool has_block = internal::is_supported_operation<has_block_t, T>;
+
+ template <typename T>
+ using has_n_blocks_t = decltype(std::declval<T const>().n_blocks());
+
+ template <typename T>
+ constexpr bool has_n_blocks =
+ internal::is_supported_operation<has_n_blocks_t, T>;
+
+ template <typename T>
+ constexpr bool is_block_vector = has_block<T> &&has_n_blocks<T>;
+} // namespace internal
/**
* A class that can be used to determine whether a given type is a block
template <typename VectorType>
struct IsBlockVector
{
-private:
- /**
- * Overload returning true if the class is derived from BlockVectorBase,
- * which is what block vectors do.
- */
- template <typename T>
- static std::true_type
- check_for_block_vector(const BlockVectorBase<T> *);
-
- /**
- * Catch all for all other potential vector types that are not block
- * vectors.
- */
- static std::false_type
- check_for_block_vector(...);
-
public:
/**
* A statically computable value that indicates whether the template
- * argument to this class is a block vector (in fact whether the type is
- * derived from BlockVectorBase<T>).
+ * argument to this class is a block vector (in fact whether the type has
+ * the functions `block()` and `n_blocks()`).
*/
- static const bool value =
- std::is_same<decltype(check_for_block_vector(std::declval<VectorType *>())),
- std::true_type>::value;
+ static const bool value = internal::is_block_vector<VectorType>;
};