Introduction
------------
This is part 1 of the style guide.  It concerns how the C/C++ syntax 
should be formated within a file.

Unified coding style is important because it eases software review 
and maintenance.  This file specifies guidelines which can be broken 
for specific cases, but should be adhered to as closely as possible.

Plastimatch can't be properly formatted automatically by GNU indent 
or astyle.  Uncrustify will do a decent job; an uncrustify configuration 
file is included in the distribution.

Conformance
-----------
Plastimatch <= 1.7 series must conform to the C++03 standard.

Supported hosts:
  Microsoft Windows 7 SP1           Visual Studio 2015 (for CUDA 8)
  Ubuntu 12.04 LTS                  gcc 4.6.3
  Debian 8 "Jessie"                 gcc 4.9.2
  CentOS 6                          gcc 4.4.7
  OSX 10.11 El Capitan              Xcode 8.2.1; clang-800; llvm 3.9.0svn

Plastimatch >= 1.8 series must conform to a restricted
subset of the C++11 standard.  This subset is restricted to 
features available in the stock compilers provided on
a fully-updated install of the supported platforms.

Supported hosts:
  Microsoft Windows 7 SP1           Visual Studio 2015 (for CUDA 8)
  Ubuntu 14.04                      gcc 4.8.4; clang 3.4
  Debian 9 "Stretch"                gcc 6.3.0; clang 3.8.1
  OSX 10.11 El Capitan              Xcode 8.2.1; clang-800; llvm 3.9.0svn

Unsupported:
  CentOS 7                          CMake version too old: 2.8.12.2

Plastimatch >= 1.9.3 may use all C++11 features.

Plastimatch >= 1.9.3-483d43ee (2022-05-24) aims to support the following
platforms:

Supported hosts:
  Microsoft Windows 7 SP1           Visual Studio ???
  Ubuntu 16.04.7                    gcc 5.3.1; clang 3.8; cmake 3.5.1;
  	 			    dcmtk 3.6.1; itk 4.9.0
  Debian 11 "Stretch"               gcc 10.2.1; clang 11.0.1; cmake 3.18.4;
  	    			    dcmtk 3.6.5; itk 4.13.3
  OSX ???                           ???

Plastimatch HEAD aims to support the following platforms:

  Debian testing                    (varies)
  Debian sid                        (varies)
  Arch linux                        (varies)
  (??) Add CentOS Stream

Files
-----
Source code files should use Unix-style end-of-line characters.
All source code should be written in 7-bit clean ASCII.

Third-party code
----------------
Third-party code should be placed in separate files, and should be 
clearly identified, so that no mistake in licensing occurs.

Indentation
-----------
Indentation should be 4 spaces.  Tabs are not allowed.
For Microsoft Visual Studio compilers, you should adjust your setting.

Line breaking
-------------
Code should be limited to 80 columns when possible.  Use typedefs to 
assist in this process.

Curly braces
------------
Use GNU curly brace style (curly on its own line) for function 
definitions, and K&R curly brace style (curly on same line as conditional)
everywhere else.

Always use curly braces for if/do/while/for statements, even if there 
is only one statement in the block.

For a simple else clause, cozy it up with the previous right curly.  
For testing multiple cases, move the else keyword to a new line.

Examples:

    int
    foo (int bar)
    {
        if (bar == 3) {
            return 1;
        } else {
            return 0;
        }
    }

    int
    foo (int bar)
    {
        if (bar == 3) {
            return 1;
        }
        else if (bar == 5) {
            return 2;
        }
	else {
            return 0;
	}
    }

Switch statement
----------------
Case labels are not indented in the switch statement.  A default label 
is required (even if there is no code).

    switch (x) {
    case a:
        code;
    case b:
        code;
    case c:
    default:
        code;
    }

Function definitions
--------------------
Declaritors and return values go on a separate line (GNU style):

    static int
    foo (int bar)
    {

Explicit "void" in the argument list is discouraged::

    void
    foo ()   // rather than foo (void)
    {

Horizontal whitespace
---------------------
Horizontal whitespace is used between operators and operands.  
Conditionals should be laid out like this:

    if (bar == 3 && baz > 4) {

Function calls like this:

    foo (a, b);

When there are no arguments, you may omit the space:

    foo();

When the return value is used with member reference, omitting space
is preferred::

    foo(bar,baz)->boo().fuz

Pointers and references
-----------------------
As per linux kernel style, put the '*' adjacent to the data name or 
function name and not adjacent to the type name.

    char *foo;
    char *bar (char *baz, char **boo);

The reason for this rule is it allows the declaration of multiple 
variables of the same type in a single statement.

    char *p, *q, *pv, *pq;

However, references go together with the type rather than the name.

    char& linux_banner = s1;
    char& bar (char& baz, char*& boo);

Vertical whitespace
-------------------
A single empty line is used between functions or between 
two groups of code.

Identifier naming
-----------------
Prefer English words to abbreviations.  Words are separated by 
underscores.  Use lowercase for function names, variable names, 
and structure names.  Use all upper case for constants.

    struct long_list {
        int list_length;
        void *list_items;
    }

    int
    my_function (struct long_list employee_list)
    {
        const int DESIRED_LENGTH = 3;
        employee_list->list_length = DESIRED_LENGTH;
    }

Names for typedefs and C++ classes should capitalize only the first letter.
Member names are lower case.

    class Volume_resizer {
    public:
        int foo;
	void bar (void);
    }

    void
    Volume_resizer::bar (void)
    {
        code;
    }
