Contents
Contributing

Overview

Contributions to the Balau library are welcome. The easiest way to contribute is to create a fork of the library's repository and submit pull requests for new or enhanced features.

The Balau library has been conceived for two distinct aims:

Contributions to the injector, logging framework, and test runner are likely to be incremental improvements and bug fixes. Contributions of new components and improvements to other existing components and utilities are open to our imagination and creativity.

Planned features

The general aim of the library's development is reactive rather than proactive. If a useful feature for enterprise quality C++ application development is missing, convoluted, or lacking in features in the C++ standard library or Boost libraries, then the feature is a good candidate for development and inclusion in Balau.

If an existing feature in the standard library or Boost exists and is designed as low level, fine grained, or does not have a straight forward API, then it would be useful to develop a corresponding Balau feature with a simple and intuitive API, as a high level facade of the standard library or Boost feature.

Consequently, there is no complex plan of planned features to be added to the library. The current list of planned features can be seen on the planned features page.

License

Balau is licensed under the Boost Software License - Version 1.0 - 2003. All contributions will need to be licensed under the same license or under a license that allows relicensing under the Boost license.

Repository

The main repository is hosted at https://github.com/borasoftware/balau.

Guidelines

The following guidelines may help with contributions. In addition to avoiding defects, the aim is to maintain an easy to understand code base in order to facilitate with rapid application development.

General

Testing

Strings

Const correctness

Concurrency

Memory management

Templates

Macros

Documentation

Code style

The aim of the code style used in the Balau library is maximum readability. The following sub-sections discuss aspects of the code style.

Indentation

Balau code style uses smart tab indenting. This allows developers to choose the tab size they desire in their source code editor, whilst maintaining correct alignment of vertically aligned items. Indentation size is thus not specified in this code style.

Files

Lines should be limited to 120 characters, when viewed with a tab size of 4 characters. Comment lines should normally be limited to approximately 80 characters.

Newlines in files must be LF, not CRLF or CR. Files should end with a newline. Whitespace should be removed at the ends of lines (configure the IDE to do it for you on saving).

Files should be named "([A-Z][a-z]*)+.hpp" for header files and "([A-Z][a-z]*)+.cpp" for body files.

Files should be grouped into a hierarchy of folders, the names of which are normally the same as the local namespace of the files contained within. The folder structure should normally follow the namespace structure.

Headers should use include barriers, the names of which exactly follow the names in the folder hierarchy in which the file is situated. The #pragma once definition should not be used. This will be revised when C++20 modules are standardized.

Includes in header files should be avoided when possible (use incomplete declarations). Otherwise, the full include path of non test header files should be used between < and > tokens.

			// Example include in header file.
			#include <Balau/Network/Http/Server/HttpWebApp.hpp>
		

Identifiers

Identifiers should be styled according to the following rules.

Metadata naming conventions (type, kind) must not be used (use an IDE that indicates identifier semantics for you). Semantic apps identifiers should mostly be avoided, apart for template parameter identifiers.

Spacing

Spacing of source code tokens aims to maximise visual grouping of related tokens, whilst maintaining a compact representation. The spacing rules are specified as a subtractive list. All tokens should be surrounded by a space, with the exception of the following, which do not have space before and/or after them:

Braces

Opening '{' braces are placed on the same line as the associated statement.

Single line code blocks should not be used.

Single line code blocks must use braces.

			// Single line code block in if statement.
			if (i < 0) {
				foo();
			}
		

Case blocks within switch statements should also use braces.

			// Switch statement case blocks.
			switch (type) {
				case Type::Simple: {
					foo();
					break;
				}

				case Type::Composite: {
					foo2();
					break;
				}

				default: {
					throwError();
					break;
				}
			}
		

Horizontal/vertical

This principal maximises the readability of parameter lists, enum entries, argument lists, and other delimited lists found in the source code.

The general idea is that it is easiest to read a delimited list when it is presented either in a single line or as a vertically aligned list. The choice of the two approaches is dictated by the length of the line when the delimited list is presented on a single line. If a single line fits within the 120 character limit, a single line is chosen. Otherwise, a vertically aligned list is chosen.

The following extracts illustrate this approach on method parameter lists.

			// From HttpWebApp class.

			public: virtual void handleGetRequest(HttpSession & session, const Request & request) = 0;
		

In this example, the method's header fits on a single line without overrunning the 120 character limit.

			// From HttpServer class.

			public: HttpServer(std::shared_ptr<Injector> injector,
			                   const std::string & serverIdentification,
			                   const TCP::endpoint & endpoint,
			                   std::string threadNamePrefix_,
			                   size_t workerCount_,
			                   std::shared_ptr<HttpWebApp> httpHandler,
			                   std::shared_ptr<WsWebApp> wsHandler,
			                   std::shared_ptr<MimeTypes> mimeTypes = MimeTypes::defaultMimeTypes);
		

In this example, the method's header would overrun the 120 character limit if it were presented on a single line, so the parameter list is arranged vertically aligned.

Delimiters

With the exception of commas in function and method parameter lists (as illustrated in the previous code example), the delimiters in a vertically aligned, delimiter separated list are each considered to belong to the following item in the list.

For example, the commas in the vertically delimited superclass call in the following code extract lead the arguments.

			protected: MultiProcessTestRunnerExecutor(CompositeWriter & writer_,
			                                          bool useNamespaces_,
			                                          GroupedTestCaseMap & testCases,
			                                          unsigned int concurrencyLevel_)
				: TestRunnerExecutor(
					  std::unique_ptr<TestResultQueue>(new MultiProcessTestResultQueue)
					, writer_
					, useNamespaces_
					, testCases
					, true
				)
				, concurrencyLevel(concurrencyLevel_)
				, sharedMemoryNamePrefix(createSharedMemoryNamePrefix()) {}
		

This code extract also illustrates comma delimited field initialisation.

Closing brackets

When a vertically aligned list is used within opening and closing brackets/parentheses, the closing bracket/parenthesis is placed on a newline. An example of this is shown in the previous code extract. The following is an example with two levels.

			tests.emplace_back(
				FlattenedTestCase(
					  testIndex
					, executionModels
					, preText
					, ""
					, testCase.name
					, testCase.group
					, std::move(testCase.method)
				)
			);
		

Visibility prefixes

The visibility prefixes are the public, protected, and private tokens used in class declarations.

In Balau sources, class declarations use explicit visibility prefixes on all declaration items (fields, methods, inner class/enum declarations). This provides physically colocated visibility information for all items, avoiding the need to search upwards in the source code for the visibility of a class item and declaring that the item is part of a class declaration.