Manual docs tweaks still in preparation for including docs with code pushes
This commit is contained in:
		@@ -174,9 +174,9 @@ We list the most frequently used macros below. For a complete list, see file
 | 
			
		||||
### Multi-threaded Tests
 | 
			
		||||
 | 
			
		||||
Google Test is thread-safe where the pthread library is available. After
 | 
			
		||||
`#include "gtest/gtest.h"`, you can check the `GTEST_IS_THREADSAFE` macro to see
 | 
			
		||||
whether this is the case (yes if the macro is `#defined` to 1, no if it's
 | 
			
		||||
undefined.).
 | 
			
		||||
`#include "gtest/gtest.h"`, you can check the
 | 
			
		||||
`GTEST_IS_THREADSAFE` macro to see whether this is the case (yes if the macro is
 | 
			
		||||
`#defined` to 1, no if it's undefined.).
 | 
			
		||||
 | 
			
		||||
If Google Test doesn't correctly detect whether pthread is available in your
 | 
			
		||||
environment, you can force it with
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,24 @@
 | 
			
		||||
## Using GoogleTest from various build systems ##
 | 
			
		||||
## Using GoogleTest from various build systems
 | 
			
		||||
 | 
			
		||||
GoogleTest comes with pkg-config files that can be used to determine all
 | 
			
		||||
necessary flags for compiling and linking to GoogleTest (and GoogleMock).
 | 
			
		||||
Pkg-config is a standardised plain-text format containing
 | 
			
		||||
 | 
			
		||||
  * the includedir (-I) path
 | 
			
		||||
  * necessary macro (-D) definitions
 | 
			
		||||
  * further required flags (-pthread)
 | 
			
		||||
  * the library (-L) path
 | 
			
		||||
  * the library (-l) to link to
 | 
			
		||||
*   the includedir (-I) path
 | 
			
		||||
*   necessary macro (-D) definitions
 | 
			
		||||
*   further required flags (-pthread)
 | 
			
		||||
*   the library (-L) path
 | 
			
		||||
*   the library (-l) to link to
 | 
			
		||||
 | 
			
		||||
All current build systems support pkg-config in one way or another. For
 | 
			
		||||
all examples here we assume you want to compile the sample
 | 
			
		||||
All current build systems support pkg-config in one way or another. For all
 | 
			
		||||
examples here we assume you want to compile the sample
 | 
			
		||||
`samples/sample3_unittest.cc`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### CMake ###
 | 
			
		||||
### CMake
 | 
			
		||||
 | 
			
		||||
Using `pkg-config` in CMake is fairly easy:
 | 
			
		||||
 | 
			
		||||
``` cmake
 | 
			
		||||
```cmake
 | 
			
		||||
cmake_minimum_required(VERSION 3.0)
 | 
			
		||||
 | 
			
		||||
cmake_policy(SET CMP0048 NEW)
 | 
			
		||||
@@ -43,11 +42,10 @@ that all libraries have been compiled with threading enabled. In addition,
 | 
			
		||||
GoogleTest might also require `-pthread` in the compiling step, and as such
 | 
			
		||||
splitting the pkg-config `Cflags` variable into include dirs and macros for
 | 
			
		||||
`target_compile_definitions()` might still miss this). The same recommendation
 | 
			
		||||
goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which
 | 
			
		||||
happens to discard `-L` flags and `-pthread`.
 | 
			
		||||
goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens
 | 
			
		||||
to discard `-L` flags and `-pthread`.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Autotools ###
 | 
			
		||||
### Autotools
 | 
			
		||||
 | 
			
		||||
Finding GoogleTest in Autoconf and using it from Automake is also fairly easy:
 | 
			
		||||
 | 
			
		||||
@@ -77,8 +75,7 @@ testapp_CXXFLAGS = $(GTEST_CFLAGS)
 | 
			
		||||
testapp_LDADD = $(GTEST_LIBS)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Meson ###
 | 
			
		||||
### Meson
 | 
			
		||||
 | 
			
		||||
Meson natively uses pkgconfig to query dependencies:
 | 
			
		||||
 | 
			
		||||
@@ -96,13 +93,12 @@ testapp = executable(
 | 
			
		||||
test('first_and_only_test', testapp)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Plain Makefiles
 | 
			
		||||
 | 
			
		||||
### Plain Makefiles ###
 | 
			
		||||
Since `pkg-config` is a small Unix command-line utility, it can be used in
 | 
			
		||||
handwritten `Makefile`s too:
 | 
			
		||||
 | 
			
		||||
Since `pkg-config` is a small Unix command-line utility, it can be used
 | 
			
		||||
in handwritten `Makefile`s too:
 | 
			
		||||
 | 
			
		||||
``` Makefile
 | 
			
		||||
```Makefile
 | 
			
		||||
GTEST_CFLAGS = `pkg-config --cflags gtest_main`
 | 
			
		||||
GTEST_LIBS = `pkg-config --libs gtest_main`
 | 
			
		||||
 | 
			
		||||
@@ -120,12 +116,11 @@ testapp.o: samples/sample3_unittest.cc
 | 
			
		||||
  $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Help! pkg-config can't find GoogleTest! ###
 | 
			
		||||
### Help! pkg-config can't find GoogleTest!
 | 
			
		||||
 | 
			
		||||
Let's say you have a `CMakeLists.txt` along the lines of the one in this
 | 
			
		||||
tutorial and you try to run `cmake`. It is very possible that you get a
 | 
			
		||||
failure along the lines of:
 | 
			
		||||
tutorial and you try to run `cmake`. It is very possible that you get a failure
 | 
			
		||||
along the lines of:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
-- Checking for one of the modules 'gtest_main'
 | 
			
		||||
@@ -135,9 +130,9 @@ CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
 | 
			
		||||
 | 
			
		||||
These failures are common if you installed GoogleTest yourself and have not
 | 
			
		||||
sourced it from a distro or other package manager. If so, you need to tell
 | 
			
		||||
pkg-config where it can find the `.pc` files containing the information.
 | 
			
		||||
Say you installed GoogleTest to `/usr/local`, then it might be that the
 | 
			
		||||
`.pc` files are installed under `/usr/local/lib64/pkgconfig`. If you set
 | 
			
		||||
pkg-config where it can find the `.pc` files containing the information. Say you
 | 
			
		||||
installed GoogleTest to `/usr/local`, then it might be that the `.pc` files are
 | 
			
		||||
installed under `/usr/local/lib64/pkgconfig`. If you set
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +1,51 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
 | 
			
		||||
 | 
			
		||||
# The Problem #
 | 
			
		||||
# The Problem
 | 
			
		||||
 | 
			
		||||
Template and macro libraries often need to define many classes,
 | 
			
		||||
functions, or macros that vary only (or almost only) in the number of
 | 
			
		||||
arguments they take. It's a lot of repetitive, mechanical, and
 | 
			
		||||
error-prone work.
 | 
			
		||||
Template and macro libraries often need to define many classes, functions, or
 | 
			
		||||
macros that vary only (or almost only) in the number of arguments they take.
 | 
			
		||||
It's a lot of repetitive, mechanical, and error-prone work.
 | 
			
		||||
 | 
			
		||||
Variadic templates and variadic macros can alleviate the problem.
 | 
			
		||||
However, while both are being considered by the C++ committee, neither
 | 
			
		||||
is in the standard yet or widely supported by compilers.  Thus they
 | 
			
		||||
are often not a good choice, especially when your code needs to be
 | 
			
		||||
portable. And their capabilities are still limited.
 | 
			
		||||
Variadic templates and variadic macros can alleviate the problem. However, while
 | 
			
		||||
both are being considered by the C++ committee, neither is in the standard yet
 | 
			
		||||
or widely supported by compilers. Thus they are often not a good choice,
 | 
			
		||||
especially when your code needs to be portable. And their capabilities are still
 | 
			
		||||
limited.
 | 
			
		||||
 | 
			
		||||
As a result, authors of such libraries often have to write scripts to
 | 
			
		||||
generate their implementation. However, our experience is that it's
 | 
			
		||||
tedious to write such scripts, which tend to reflect the structure of
 | 
			
		||||
the generated code poorly and are often hard to read and edit. For
 | 
			
		||||
example, a small change needed in the generated code may require some
 | 
			
		||||
non-intuitive, non-trivial changes in the script. This is especially
 | 
			
		||||
painful when experimenting with the code.
 | 
			
		||||
As a result, authors of such libraries often have to write scripts to generate
 | 
			
		||||
their implementation. However, our experience is that it's tedious to write such
 | 
			
		||||
scripts, which tend to reflect the structure of the generated code poorly and
 | 
			
		||||
are often hard to read and edit. For example, a small change needed in the
 | 
			
		||||
generated code may require some non-intuitive, non-trivial changes in the
 | 
			
		||||
script. This is especially painful when experimenting with the code.
 | 
			
		||||
 | 
			
		||||
# Our Solution #
 | 
			
		||||
# Our Solution
 | 
			
		||||
 | 
			
		||||
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
 | 
			
		||||
Programming, or Practical Utility for Meta Programming, whichever you
 | 
			
		||||
prefer) is a simple meta-programming tool for C++. The idea is that a
 | 
			
		||||
programmer writes a `foo.pump` file which contains C++ code plus meta
 | 
			
		||||
code that manipulates the C++ code. The meta code can handle
 | 
			
		||||
iterations over a range, nested iterations, local meta variable
 | 
			
		||||
definitions, simple arithmetic, and conditional expressions. You can
 | 
			
		||||
view it as a small Domain-Specific Language. The meta language is
 | 
			
		||||
designed to be non-intrusive (s.t. it won't confuse Emacs' C++ mode,
 | 
			
		||||
for example) and concise, making Pump code intuitive and easy to
 | 
			
		||||
maintain.
 | 
			
		||||
Programming, or Practical Utility for Meta Programming, whichever you prefer) is
 | 
			
		||||
a simple meta-programming tool for C++. The idea is that a programmer writes a
 | 
			
		||||
`foo.pump` file which contains C++ code plus meta code that manipulates the C++
 | 
			
		||||
code. The meta code can handle iterations over a range, nested iterations, local
 | 
			
		||||
meta variable definitions, simple arithmetic, and conditional expressions. You
 | 
			
		||||
can view it as a small Domain-Specific Language. The meta language is designed
 | 
			
		||||
to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
 | 
			
		||||
concise, making Pump code intuitive and easy to maintain.
 | 
			
		||||
 | 
			
		||||
## Highlights ##
 | 
			
		||||
## Highlights
 | 
			
		||||
 | 
			
		||||
  * The implementation is in a single Python script and thus ultra portable: no build or installation is needed and it works cross platforms.
 | 
			
		||||
  * Pump tries to be smart with respect to [Google's style guide](https://github.com/google/styleguide): it breaks long lines (easy to have when they are generated) at acceptable places to fit within 80 columns and indent the continuation lines correctly.
 | 
			
		||||
  * The format is human-readable and more concise than XML.
 | 
			
		||||
  * The format works relatively well with Emacs' C++ mode.
 | 
			
		||||
*   The implementation is in a single Python script and thus ultra portable: no
 | 
			
		||||
    build or installation is needed and it works cross platforms.
 | 
			
		||||
*   Pump tries to be smart with respect to
 | 
			
		||||
    [Google's style guide](https://github.com/google/styleguide): it breaks long
 | 
			
		||||
    lines (easy to have when they are generated) at acceptable places to fit
 | 
			
		||||
    within 80 columns and indent the continuation lines correctly.
 | 
			
		||||
*   The format is human-readable and more concise than XML.
 | 
			
		||||
*   The format works relatively well with Emacs' C++ mode.
 | 
			
		||||
 | 
			
		||||
## Examples ##
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are meta brackets, and `$$` starts a meta comment that ends with the line):
 | 
			
		||||
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
 | 
			
		||||
meta brackets, and `$$` starts a meta comment that ends with the line):
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
$var n = 3     $$ Defines a meta variable n.
 | 
			
		||||
@@ -71,7 +70,7 @@ $if i == 0 [[
 | 
			
		||||
 | 
			
		||||
will be translated by the Pump compiler to:
 | 
			
		||||
 | 
			
		||||
``` cpp
 | 
			
		||||
```cpp
 | 
			
		||||
// Foo0 does blah for 0-ary predicates.
 | 
			
		||||
template <size_t N>
 | 
			
		||||
class Foo0 {
 | 
			
		||||
@@ -105,9 +104,10 @@ Func($for i + [[a$i]]);
 | 
			
		||||
$$ The text between i and [[ is the separator between iterations.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
will generate one of the following lines (without the comments), depending on the value of `n`:
 | 
			
		||||
will generate one of the following lines (without the comments), depending on
 | 
			
		||||
the value of `n`:
 | 
			
		||||
 | 
			
		||||
``` cpp
 | 
			
		||||
```cpp
 | 
			
		||||
Func();              // If n is 0.
 | 
			
		||||
Func(a1);            // If n is 1.
 | 
			
		||||
Func(a1 + a2);       // If n is 2.
 | 
			
		||||
@@ -115,32 +115,38 @@ Func(a1 + a2 + a3);  // If n is 3.
 | 
			
		||||
// And so on...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Constructs ##
 | 
			
		||||
## Constructs
 | 
			
		||||
 | 
			
		||||
We support the following meta programming constructs:
 | 
			
		||||
 | 
			
		||||
| `$var id = exp` | Defines a named constant value. `$id` is valid util the end of the current meta lexical block. |
 | 
			
		||||
|:----------------|:-----------------------------------------------------------------------------------------------|
 | 
			
		||||
| `$range id exp..exp` | Sets the range of an iteration variable, which can be reused in multiple loops later.          |
 | 
			
		||||
| `$for id sep [[ code ]]` | Iteration. The range of `id` must have been defined earlier. `$id` is valid in `code`.         |
 | 
			
		||||
| `$($)`          | Generates a single `$` character.                                                              |
 | 
			
		||||
| `$id`           | Value of the named constant or iteration variable.                                             |
 | 
			
		||||
| `$(exp)`        | Value of the expression.                                                                       |
 | 
			
		||||
| `$if exp [[ code ]] else_branch` | Conditional.                                                                                   |
 | 
			
		||||
| `[[ code ]]`    | Meta lexical block.                                                                            |
 | 
			
		||||
| `cpp_code`      | Raw C++ code.                                                                                  |
 | 
			
		||||
| `$$ comment`    | Meta comment.                                                                                  |
 | 
			
		||||
| `$var id = exp`                  | Defines a named constant value. `$id` is |
 | 
			
		||||
:                                  : valid util the end of the current meta   :
 | 
			
		||||
:                                  : lexical block.                           :
 | 
			
		||||
| :------------------------------- | :--------------------------------------- |
 | 
			
		||||
| `$range id exp..exp`             | Sets the range of an iteration variable, |
 | 
			
		||||
:                                  : which can be reused in multiple loops    :
 | 
			
		||||
:                                  : later.                                   :
 | 
			
		||||
| `$for id sep [[ code ]]`         | Iteration. The range of `id` must have   |
 | 
			
		||||
:                                  : been defined earlier. `$id` is valid in  :
 | 
			
		||||
:                                  : `code`.                                  :
 | 
			
		||||
| `$($)`                           | Generates a single `$` character.        |
 | 
			
		||||
| `$id`                            | Value of the named constant or iteration |
 | 
			
		||||
:                                  : variable.                                :
 | 
			
		||||
| `$(exp)`                         | Value of the expression.                 |
 | 
			
		||||
| `$if exp [[ code ]] else_branch` | Conditional.                             |
 | 
			
		||||
| `[[ code ]]`                     | Meta lexical block.                      |
 | 
			
		||||
| `cpp_code`                       | Raw C++ code.                            |
 | 
			
		||||
| `$$ comment`                     | Meta comment.                            |
 | 
			
		||||
 | 
			
		||||
**Note:** To give the user some freedom in formatting the Pump source
 | 
			
		||||
code, Pump ignores a new-line character if it's right after `$for foo`
 | 
			
		||||
or next to `[[` or `]]`. Without this rule you'll often be forced to write
 | 
			
		||||
very long lines to get the desired output. Therefore sometimes you may
 | 
			
		||||
need to insert an extra new-line in such places for a new-line to show
 | 
			
		||||
up in your output.
 | 
			
		||||
**Note:** To give the user some freedom in formatting the Pump source code, Pump
 | 
			
		||||
ignores a new-line character if it's right after `$for foo` or next to `[[` or
 | 
			
		||||
`]]`. Without this rule you'll often be forced to write very long lines to get
 | 
			
		||||
the desired output. Therefore sometimes you may need to insert an extra new-line
 | 
			
		||||
in such places for a new-line to show up in your output.
 | 
			
		||||
 | 
			
		||||
## Grammar ##
 | 
			
		||||
## Grammar
 | 
			
		||||
 | 
			
		||||
``` ebnf
 | 
			
		||||
```ebnf
 | 
			
		||||
code ::= atomic_code*
 | 
			
		||||
atomic_code ::= $var id = exp
 | 
			
		||||
    | $var id = [[ code ]]
 | 
			
		||||
@@ -159,19 +165,26 @@ else_branch ::= $else [[ code ]]
 | 
			
		||||
exp ::= simple_expression_in_Python_syntax
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Code ##
 | 
			
		||||
## Code
 | 
			
		||||
 | 
			
		||||
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). It is still
 | 
			
		||||
very unpolished and lacks automated tests, although it has been
 | 
			
		||||
successfully used many times. If you find a chance to use it in your
 | 
			
		||||
project, please let us know what you think!  We also welcome help on
 | 
			
		||||
improving Pump.
 | 
			
		||||
You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py).
 | 
			
		||||
It is still very unpolished and lacks automated tests, although it has been
 | 
			
		||||
successfully used many times. If you find a chance to use it in your project,
 | 
			
		||||
please let us know what you think! We also welcome help on improving Pump.
 | 
			
		||||
 | 
			
		||||
## Real Examples ##
 | 
			
		||||
## Real Examples
 | 
			
		||||
 | 
			
		||||
You can find real-world applications of Pump in [Google Test](https://github.com/google/googletest/tree/master/googletest) and [Google Mock](https://github.com/google/googletest/tree/master/googlemock). The source file `foo.h.pump` generates `foo.h`.
 | 
			
		||||
You can find real-world applications of Pump in
 | 
			
		||||
[Google Test](https://github.com/google/googletest/tree/master/googletest) and
 | 
			
		||||
[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
 | 
			
		||||
source file `foo.h.pump` generates `foo.h`.
 | 
			
		||||
 | 
			
		||||
## Tips ##
 | 
			
		||||
## Tips
 | 
			
		||||
 | 
			
		||||
  * If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1.
 | 
			
		||||
  * To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line.
 | 
			
		||||
*   If a meta variable is followed by a letter or digit, you can separate them
 | 
			
		||||
    using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
 | 
			
		||||
    generate `Foo1Helper` when `j` is 1.
 | 
			
		||||
*   To avoid extra-long Pump source lines, you can break a line anywhere you
 | 
			
		||||
    want by inserting `[[]]` followed by a new line. Since any new-line
 | 
			
		||||
    character next to `[[` or `]]` is ignored, the generated code won't contain
 | 
			
		||||
    this new line.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user