# Fn<> Is
Returns whether a concept is fulfilled.

Defined in | <seqan/basic.h>
Signature | `Is<TConcept>::Type Is<TConcept>::VALUE`

## Template Parameters

`TConcept` | A concept that is specialized with type(s) that should be tested for fulfilling the concept.

## Return Values

`Type` | True/`true` if `TConcept` is a fulfilled concept, otherwise False/`false`.

## Detailed Description

The Is-metafunction can be used to test types for fulfilling a concept without causing compilation errors. If `True` or `true` is returned, `TConcept` must pass the concept test via SEQAN_CONCEPT_ASSERT. It can be used to switch between different implementations depending on the concept of a type, or in combination with SEQAN_FUNC_ENABLE_IF to make a function only visible to types of certain concepts.

### Examples

    Is<StringConcept<TSeq> >::Type
    IfC<Is<ContainerConcept<TSeq> >::VALUE, T1, T2>::Type

    std::cout << Is<IntegerConcept<int> >::VALUE << std::endl;     // 1
    std::cout << Is<IntegerConcept<double> >::VALUE << std::endl;  // 0

Define a hierarchy of concepts and two models `Alice` and `Bob` that implements some of them. Is determines which concepts are explicitly or implicitly fulfilled.

    struct Alice {};
    struct Bob {};

    SEQAN_CONCEPT(ConceptA, (T)) {};
    SEQAN_CONCEPT(ConceptB, (T)) {};
    SEQAN_CONCEPT_REFINE(ConceptC, (T), (ConceptA)(ConceptB)) {};
    SEQAN_CONCEPT_REFINE(ConceptD, (T), (ConceptC)) {};

    template<>   // Alice has no template arguments
    SEQAN_CONCEPT_IMPL(Alice, (ConceptA)(ConceptB));

    template<>   // Bob has no template arguments
    SEQAN_CONCEPT_IMPL(Bob, (ConceptC));

    std::cout << Is< ConceptA<Alice> >::VALUE << std::endl; // 1
    std::cout << Is< ConceptB<Alice> >::VALUE << std::endl; // 1
    std::cout << Is< ConceptC<Alice> >::VALUE << std::endl; // 0
    std::cout << Is< ConceptD<Alice> >::VALUE << std::endl; // 0

    std::cout << Is< ConceptA<Bob> >::VALUE << std::endl;   // 1
    std::cout << Is< ConceptB<Bob> >::VALUE << std::endl;   // 1
    std::cout << Is< ConceptC<Bob> >::VALUE << std::endl;   // 1
    std::cout << Is< ConceptD<Bob> >::VALUE << std::endl;   // 0

## See Also

- SEQAN_CONCEPT_ASSERT
- SEQAN_FUNC_ENABLE_IF

#### Dox Sources

    /*!
     * @mfn Is
     *
     * @headerfile <seqan/basic.h>
     *
     * @brief Returns whether a concept is fulfilled.
     *
     * @signature Is<TConcept>::Type
     * @signature Is<TConcept>::VALUE
     *
     * @tparam TConcept A concept that is specialized with type(s) that should be
     *                  tested for fulfilling the concept.
     *
     * @return Type @link LogicalValuesTags#True @endlink/<tt>true</tt> if
     *              <tt>TConcept</tt> is a fulfilled concept, otherwise @link
     *              LogicalValuesTags#False @endlink/<tt>false</tt>.
     *
     * The @link Is @endlink-metafunction can be used to test types for fulfilling a
     * concept without causing compilation errors. If <tt>True</tt> or <tt>true</tt>
     * is returned, <tt>TConcept</tt> must pass the concept test via @link
     * ConceptChecking#SEQAN_CONCEPT_ASSERT @endlink. It can be used to switch
     * between different implementations depending on the concept of a type, or in
     * combination with @link EnableIfFunctionality#SEQAN_FUNC_ENABLE_IF @endlink to
     * make a function only visible to types of certain concepts.
     *
     * @section Examples
     *
     * @code{.cpp}
     * Is<StringConcept<TSeq> >::Type
     * IfC<Is<ContainerConcept<TSeq> >::VALUE, T1, T2>::Type
     *
     * std::cout << Is<IntegerConcept<int> >::VALUE << std::endl;     // 1
     * std::cout << Is<IntegerConcept<double> >::VALUE << std::endl;  // 0
     * @endcode
     *  Define a hierarchy of concepts and two models <tt>Alice</tt> and
     * <tt>Bob</tt> that implements some of them. @link Is @endlink determines which
     * concepts are explicitly or implicitly fulfilled.
     *
     * @code{.cpp}
     * struct Alice {};
     * struct Bob {};
     *
     * SEQAN_CONCEPT(ConceptA, (T)) {};
     * SEQAN_CONCEPT(ConceptB, (T)) {};
     * SEQAN_CONCEPT_REFINE(ConceptC, (T), (ConceptA)(ConceptB)) {};
     * SEQAN_CONCEPT_REFINE(ConceptD, (T), (ConceptC)) {};
     *
     * template<>   // Alice has no template arguments
     * SEQAN_CONCEPT_IMPL(Alice, (ConceptA)(ConceptB));
     *
     * template<>   // Bob has no template arguments
     * SEQAN_CONCEPT_IMPL(Bob, (ConceptC));
     *
     * std::cout << Is< ConceptA<Alice> >::VALUE << std::endl; // 1
     * std::cout << Is< ConceptB<Alice> >::VALUE << std::endl; // 1
     * std::cout << Is< ConceptC<Alice> >::VALUE << std::endl; // 0
     * std::cout << Is< ConceptD<Alice> >::VALUE << std::endl; // 0
     *
     * std::cout << Is< ConceptA<Bob> >::VALUE << std::endl;   // 1
     * std::cout << Is< ConceptB<Bob> >::VALUE << std::endl;   // 1
     * std::cout << Is< ConceptC<Bob> >::VALUE << std::endl;   // 1
     * std::cout << Is< ConceptD<Bob> >::VALUE << std::endl;   // 0
     * @endcode
     *
     *
     * @see EnableIfFunctionality#SEQAN_FUNC_ENABLE_IF
     * @see ConceptChecking#SEQAN_CONCEPT_ASSERT
     */