Page Language Entity Types

SeqAn is a C++ template library that relies on template metaprogramming to achieve good performance and maintainability. Our way of using C++ template metaprogramming introduces some approaches that might be unfamiliar to you.

For example, functions that would to be member functions in OOP are technically implemented as global functions. For this reason we semantically annotated all variables, functions, metafunctions, classes, etc. throughout the whole online documentation with a small label to tell you with what you're semantically dealing - although there sometimes is no technical counterpart.

We call the above mentioned things like variables, functions, metafunctions, classes, etc. language entity types. This page serves as a reference for the language entity types used in SeqAn and answers the following questions:

  • What is each language entity type originally meant to do?
  • How is each language entity type used in SeqAn?
  • What variants of each language entity type exist?

Typedef

Typedefs are a common, standardized C++ language feature that allows one to give custom names to arbitrary types.

When programming SeqAn, they are often used for giving short names to complicated, nested template instantiations or to the result of a metafunction.

Example

The following example shows you how the lengthy type Iterator<String<char, Alloc<> >::Type is shortened to TIt. (Iterator is a metafunction that returns the iterator type of a container).

using namespace seqan2;

typedef typename Iterator<String<char, Alloc<> >::Type TIt;

for (TIt it = begin(str, Standard()); it != end(str, Standard()); ++it)
    std::cout << *it;

Concept

Concepts are a rarely used, not yet standardized C++ language feature. They are informal interfaces that define a set of requirements for a type.

In contrast to Java interfaces, C++ concepts can be added to custom types and built-in types without having access to the source code of the type. You might know the typical (Java) interface limitation if you ever tried to make a built-in type implement a custom interface.

Concepts are currently still a proposal for a future C++ language release and thus not respected by IDEs and compilers. As a consequence, your IDE can't tell you if a concept's function is actually implemented for a given class or not. You may still expect the implementation to exist for an implementing class because this is what the SeqAn library guarantees. Functions and metafunctions that are part of a concept are called interface functions respectively interface metafunctions.

Example

You can expect the globally implemented interface functions appendValue, append, assignValue and many others to work with String because they are part of StringConcept which is implemented by String.

External Resources

See the concepts chapter at cppreference.com.

Class

Classes are a common, standardized C++ language feature. It allows the definition of custom types using classes that basically encapsulate variables and functions.

In SeqAn, classes usually have few or no technical member functions. Instead, their member functions are implemented globally and typically expect the class instance as the first argument.

SeqAn provides many class templates that are roughly comparable to Java Generic.

Example

The following example shows a class template for objects that can hold two values of the same type.

template class<T>
class Pair
{
public:
    T values [2];

    Pair (T first, T second)
    {
      values[0] = first;
      values[1] = second;
    }
};

Pair can now be instantiated using Pair<int> myPair1(42, 115); or Pair<float>(3.141, 2.72);.

Variants

specialization

Specializations are similar to subclasses but the mechanism uses template specialization instead of C++ subclassing.

In SeqAn, this is widely used in containers such as strings or indices to achieve good performance.

struct

C++ inherited structs from C. Structs and classes are very similar, the main difference is that all members of structs are declared with public visibility by default.

In SeqAn, structs are used instead of classes for simple record types that only store data and do not provide any major logic through interface or member functions.

Example

The following shows a class Klass that is specialized two times using the tags OneKlass and AnotherKlass.

struct OneKlass_;
typedef seqan2::Tag<OneKlass_> OneKlass;

struct OtherKlass_;
typedef seqan2::Tag<OtherKlass_> OtherKlass;

template <typename TSpec>
class Klass;
// Note that the body here is optional.  In this case, we create this class "abstract".

template <>
class Klass<OneKlass>
{
public:
    int x;
};

template <>
class Klass<OtherKlass>
{
public:
    double x;
};

Enum

Enums are a common, standardized C++ feature that allow the definition of a set of named, enumerable integral constants.

In SeqAn, they are mainly used to define the integral value of the VALUE member of a metafunction, e.g. Log2<32>::VALUE.

Example

In the following example, the enum MyEnum with the constants ENUM_VALUE1 and ENUM_VALUE2 is defined.

enum MyEnum
{
     ENUM_VALUE1,
     ENUM_VALUE2
};

You may later write MyEnum x = ENUM_VALUE2.

The following example defines the metafunction QualityValueSize using a template struct. The struct contains an unnamed enum with a single integral constant named VALUE that has the value 63.

template <>
struct QualityValueSize<Dna5Q>
{
    enum { VALUE = 63 };
};

Later you may write int x = QualityValueSize<Dna5Q>::VALUE whichs results in 63 and is calculated at compile-time.

If the enum was named (e.g. MyEnum) you would have to write int x = QualityValueSize<Dna5Q>::MyEnum::VALUE (TODO: How is the correct syntax?!?!?!).<

Metafunction

Metafunctions are a rarely used, not yet standardized C++ language feature that allows for compile-time evaluated functions.

In contrast to standard functions that use objects as arguments and optionally return an object, metafunctions use types as arguments and return a type or an integral value.

In SeqAn, they are mainly used to retrieve the appropriate type for a specific task, such as the iteration over a ContainerConcept.

See the Metafunctions in the More C++ Idioms Wikibook for more information.

Example

The following two examples iterate over each character of str and print it. The first example is not recommended but purely demonstrates the use of a metafunction. The second example shows the recommended use of metafunctions in combination with a typedef.

using namespace seqan2;

for (typename Iterator<String<char, Alloc<> >::Type it = begin(str, Standard()); it != end(str, Standard()); ++it)
    std::cout << *it;
std::cout << "\n";
using namespace seqan2;

typedef typename Iterator<String<char, Alloc<> >::Type TIt;

for (TIt it = begin(str, Standard()); it != end(str, Standard()); ++it)
    std::cout << *it;
std::cout << "\n";

Variants

Global Metafunction

Global metafunctions are technically and semantically implemented globally.

A typical global metafunctions is Log2.

Interface Metafunction

Interface metafunctions semantically belong to one or more concepts. Types that implement a specific concept are guaranteed to work with all interface functions belonging to this specific concept.

Example: ClassString implement ConceptStringConcept. Since the metafunction fn()append is part of ConceptStringConcept, fn()append accepts ClassString as an argument.

Although concepts are formally specified they are not yet part of the C++ language and thus ignored by compilers. As a consequence your IDE will pretty certainly not stop you from using a metafunction with a type that does not implements one of the metafunction's concepts.

Function

Functions are a common, fundamental C++ feature and the basic building block for programs.

Example

A runnable C++ program always contains a main function.

int main()
{
  return 0;
}

Variants

Global Function

Global functions are defined outside any class and not directly connected to one class. They might be in a namespace (such as the seqan namespace).

Examples are the functions for the global and local alignment, e.g. globalAlignment and localAlignment. These functions use many classes to realize their behaviour but do not directly belong to any of the signature's data types.
Interface Function

SeqAn uses global interface functions instead of member functions. This allows (1) to extend types without access to their source code and (2) to use template-based inheritance and static type dispatching.

Member Function

Member functions are a standard C++ function. They are defined in classes or structs.

In SeqAn, few member functions are used in the interface of types. Of course, the constructor, and destructor are always implemented as member functions.

Tag

Tags are classes that are only used for their type. They are often used for tag-based dispatching.

Variable

Variables are a standard C++ feature.

Adaption

Adaptions are collections of functions and metafunctions that make a type T follow an interface C. This can be used to make a class from an external library follow a SeqAn concept.

Example

The following shows a small part of the adaption of std::string to the ContainerConcept: the implementation of the length functions.

#include <string>

namespace seqan2
{

size_t length(std::string const & str)
{
    return str.size();
}

};  // namespace seqan2

Macro

Macros are pieces of code evaluated by the C preprocessor.

All SeqAn macros are prefixed with SEQAN_.

Example

// If SeqAn would provide a macro to compute the square of a number, it would
// look as follows.
#define SEQAN_SQUARE(x) (x * x)

// In applications and user code, it could be used as follows:
#define SQUARE(x) (x * x)

// The SeqAn library defines the SEQAN_ASSERT* macros, for example:
SEQAN_ASSERT_EQ(SQUARE(10), 100);

Template Parameter

Templates can take types or constant integral values as parameters.