Overview
--------

This document sets out the expected coding style for those who wish to participate in this project. With this standard we will maintain a readable codebase that can be easily cannibalised by new and old developers alike.

To ensure the codebase meets this standard please install the supplied [GIT pre-commit](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) hook into your local copy. You're also required to install the [Artistic Style](http://astyle.sourceforge.net/) tool on your system for this hook to be successful; you must have version 2.05 or greater installed.

```
cd restbed/
cp tool/git/pre-commit .git/hooks
chmod +x .git/hooks/pre-commit
```

**most importantly:** "know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!" -- Guido van Rossum, Barry Warsaw, Nick Coghlan.

Interpretation
--------------

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in [RFC 2119](http://tools.ietf.org/pdf/rfc2119.pdf).

Table of Contents
-----------------

1.	[Overview](#overview)
2.	[Interpretation](#interpretation)
3.	[Brackets](#brackets)
4.	[Indentation](#indentation)
5.	[Comments](#comments)
6.	[Properties/Variables](#propertiesvariables)
7.	[Classes](#classes)
8.	[Enumerations](#enumerations)
9.	[Structures](#structures)
10.	[Methods/Functions](#methodsfunctions)
11.	[Whitespace](#whitespace)
12.	[Pointers/References](#pointersreferences)
13.	[Exceptions](#exceptions)
14.	[Namespaces](#namespaces)
15.	[Optimisations](#optimisations)

### Brackets

-	Allman style broken braces, and avoid unbraced one line conditional statements.

```C++
if ( condition == true )
{
  ...
}
else
{
 ...
}
```

### Indentation

-	Do **not** use tabs. All indentation is of 4 spaces.
-	Class, Namespace, Struct, If, For, Switch, etc.. statements **must** be indented.

```C++
namespace transport
{
  class Car( void )
  {
    public:
      Car( const int number_of_wheels ) : m_number_of_wheels
      {
        switch( m_number_of_wheels )
        {
            case 1:
              break;
            default:
              break;
        }
      }

    private:
      uint8_t m_number_of_wheels;
  }
}
```

### Comments

-	Comments **should** be avoided as they add an additional layer of management and/or technical-debt.
-	Commenting is just as ineffective as poorly readable code.
-	Code should be self documenting with descriptive naming conventions applied to functions, variables, files, directories, etc...
-	Commenting may be a sign you need to split the logic into multiple manageable blocks.

### Properties/Variables

-	Property and Variables names **must** follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
-	Property and Variables **must** be initialised to a known state on declaration.

```C++
int limit = 0;
int person_age = 21;
string name = String::empty;
```

### Classes

-	Class property names **must** be prefixed with `m_` and follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
-	Class properties **must** be initialised to a known state on instance creation.
-	Class properties **must** be private in scope.
-	Class getter/setter accessor methods **must not** return non-const pointers/references.
-	There **must** be **no** using namespace declarations in class header files.
-	Forward declarations are favoured over `#include` within class header files; with the exception of the standard template library.
-	Empty method bodies (when unavoidable) *shall* be marked with a single return.
-	Public classes **must** implement an [opaque pointer](http://en.wikipedia.org/wiki/Opaque_pointer).
-	Class names **must** start each word boundary with an UPPERCASED letter.

```C++
class Person
{
  public:
    Person( void ) : m_age( 0 )
    {
      return;
    }

    int get_age( void ) const
    {
      return m_age;
    }

    void set_age( const int value )
    {
      m_age = value;
    }

  private:
    int m_age;.
}
```

### Enumerations

-	Enumerations **must** be strongly typed.
-	Enumeration fields **must** be UPPERCASED.
-	Enumeration fields **must** be initialised to a known state.
-	Enumeration names **must** start each word boundary with an UPPERCASED letter.

```C++
enum LogLevel : int
{
  INFO = 0000,
  DEBUG = 1000,
  FATAL = 2000,
  ERROR = 3000,
  WARNING = 4000,
  SECURITY = 5000
}
```

### Structures

-	Structure property names **must** follow the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
-	Structure properties **must** be initialised to a known state on instance creation.
-	Structure names **must** start each word boundary with an UPPERCASED letter.

```C++
struct HttpRequest
{
  Bytes body = { };
  uint16_t port = 80;
  double version = 1.1;
  std::string host = "";
  std::string path = "/";
  std::string method = "GET";
  std::multimap< std::string, std::string > headers { };
}
```

### Methods/Functions

-	Functions and Methods **must** use the [Snake-case naming convention](https://en.wikipedia.org/wiki/snake_case).
-	Functions and Methods **should** perform one mental operation which is reflected in their name.
-	Function and Method declarations **should** avoid similar argument types.
-	It is recommended that Functions and Methods are no greater than 70 lines of code. If you find that the [LOC](https://en.wikipedia.org/wiki/Source_lines_of_code) exceed this limit, it may be an indication that it is performing more than one mental operation; see rule 2.

```C++
int ping( Hostname hostname, Interface interface, int16_t port )
{
  auto port = port;
  auto hostname = hostname.to_string( );
  auto interface = hostname.to_string( )

  ...

  return ttl;
}
```

### Whitespace

-	Whitespace is free, don't be scared to use it.

```C++
int process_exit_status = 0;
const string filename = "/bin/ls";

do
{
  Process reaction = load_process( filename );
  reaction.run( );

  process_exit_status = reaction.get_exit_status( );
}
while ( process_exit_status not_eq -1 );
```

### Pointers/References

-	Pointers and References **must** be aligned to the data type (left).

```C++
int* age = nullptr;
char* forename = nullptr;
string& surname = m_surname;
```

### Exceptions

-	Logic within catch-blocks **must** be short & sweet.
-	Name exceptions per Java styling.

```C++
try
{
  start( );
}
catch ( const invalid_argument& ia )
{
  stop( );
}
catch ( const runtime_error& re )
{
  stop( );
}
catch ( const exception& ex )
{
  stop( );
}
```

### Namespaces

-	**Do not** include entire Namespaces, import only the artifact you're interested in.
-	Namespace names **must only** contain lowercased letters.

```C++
using std::mutex;
using std::string;
using std::thread;

namespace restbed
{
  ...
}
```

### Optimisations

-	Avoid premature optimisation, **readable, maintainable code is more important**.
