# 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_int_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_int_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_int_t.

Before igraph 1.0, igraph_int_t was called igraph_integer_t. This is still available as an alias to igraph_int_t and will remain accessible until at least version 2.0 of the library.

Since the size of a variable of type igraph_int_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_int_t, and you must use this macro in `printf` format strings to avoid compiler warnings.

Similarly to how igraph_int_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_int_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_int_t and igraph_uint_t are provided by the constants named `IGRAPH_INTEGER_MIN`, `IGRAPH_INTEGER_MAX`, `IGRAPH_UINT_MIN` and `IGRAPH_UINT_MAX`.

## Setup and initialization

Certain parts of &igraph; must be initialized before first use, which can be accomplished using the setup functions below. As of igraph 1.0, most functions will work correctly even if setup is not performed, as currently the only setup action is seeding the random number generator. That said, it is strongly recommended to call `igraph_setup()` before using any other function, as future &igraph; versions may add critical initialization steps.

## The basic interface

### Graph constructors and destructors

### Basic query operations

### Adding and deleting vertices and edges

## Miscellaneous macros and helper functions