# Basic data types and interface

## The &igraph; data model

The &igraph; library can handle directed and undirected graphs. The &igraph; graphs are multisets of ordered (if directed) or unordered (if undirected) labeled pairs. The labels of the pairs plus the number of vertices always starts with zero and ends with the number of edges minus one. In addition to that, a table of metadata is also attached to every graph, its most important entries being the number of vertices in the graph and whether the graph is directed or undirected.

Like the edges, the &igraph; vertices are also labeled by numbers between zero and the number of vertices minus one. So, to summarize, a directed graph can be imagined like this:

      ( vertices: 6,
        directed: yes,
        {
         (0,2),
         (2,2),
         (3,2),
         (3,3),
         (3,4),
         (3,4),
         (4,3),
         (4,1)
        }
      )

Here the edges are ordered pairs or vertex ids, and the graph is a multiset of edges plus some metadata.

An undirected graph is like this:

      ( vertices: 6,
        directed: no,
        {
         (0,2),
         (2,2),
         (2,3),
         (3,3),
         (3,4),
         (3,4),
         (3,4),
         (1,4)
        }
      )

Here, an edge is an unordered pair of two vertex IDs. A graph is a multiset of edges plus metadata, just like in the directed case.

It is possible to convert between directed and undirected graphs, see the `igraph_to_directed()` and `igraph_to_undirected()` functions.

&igraph; aims to robustly support multigraphs, i.e. graphs which have more than one edge between some pairs of vertices, as well as graphs with self-loops. Most functions which do not support such graphs will check their input and issue an error if it is not valid. Those rare functions which do not perform this check clearly indicate this in their documentation. To eliminate multiple edges from a graph, you can use `igraph_simplify()`.

## General conventions of &igraph; functions

&igraph; has a simple and consistent interface. Most functions check their input for validity and display an informative error message when something goes wrong. In order to support this, the majority of functions return an error code. In basic usage, this code can be ignored, as the default behaviour is to abort the program immediately upon error. See the section on error handling for more information on this topic.

Results are typically returned through output arguments, i.e. pointers to a data structure into which the result will be written. In almost all cases, this data structure is expected to be pre-initialized. A few simple functions communicate their result directly through their return value—these functions can never encounter an error.

## Atomic data types

&igraph; introduces a few aliases to standard C data types that are then used throughout the library. The most important of these types is `igraph_integer_t`, which is an alias to either a 32-bit or a 64-bit signed integer, depending on whether &igraph; was compiled in 32-bit or 64-bit mode. The size of `igraph_integer_t` also influences the maximum number of vertices that an &igraph; graph can represent as the number of vertices is stored in a variable of type `igraph_integer_t`.

Since the size of a variable of type `igraph_integer_t` may change depending on how &igraph; is compiled, you cannot simply use `%d` or `%ld` as a placeholder for &igraph; integers in `printf` format strings. &igraph; provides the `IGRAPH_PRId` macro, which maps to `d`, `ld` or `lld` depending on the size of `igraph_integer_t`, and you must use this macro in `printf` format strings to avoid compiler warnings.

Similarly to how `igraph_integer_t` maps to the standard size signed integer in the library, `igraph_uint_t` maps to a 32-bit or a 64-bit unsigned integer. It is guaranteed that the size of `igraph_integer_t` is the same as the size of `igraph_uint_t`. &igraph; provides `IGRAPH_PRIu` as a format string placeholder for variables of type `igraph_uint_t`.

Real numbers (i.e. quantities that can potentially be fractional or infinite) are represented with a type named `igraph_real_t`. Currently `igraph_real_t` is always aliased to `double`, but it is still good practice to use `igraph_real_t` in your own code for sake of consistency.

Boolean values are represented with a type named `igraph_bool_t`. It tries to be as small as possible since it only needs to represent a truth value. For printing purposes, you can treat it as an integer and use `%d` in format strings as a placeholder for an `igraph_bool_t`.

Upper and lower limits of `igraph_integer_t` and `igraph_uint_t` are provided by the constants named `IGRAPH_INTEGER_MIN`, `IGRAPH_INTEGER_MAX`, `IGRAPH_UINT_MIN` and `IGRAPH_UINT_MAX`.

## The basic interface

### Graph constructors and destructors

### Basic query operations

### Adding and deleting vertices and edges

## Miscellaneous macros and helper functions