Merge branch 'doc' into develop
This commit is contained in:
commit
811c89a50b
@ -1,4 +1,5 @@
|
||||
include(CMakeParseArguments)
|
||||
include(ProcessorCount)
|
||||
|
||||
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
|
||||
HINTS
|
||||
@ -26,6 +27,7 @@ function(add_sphinx_doc SRC_DIR)
|
||||
set(multiValueArgs VARS TEMPLATE_VARS)
|
||||
|
||||
cmake_parse_arguments(PARSE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
ProcessorCount(N)
|
||||
|
||||
set(ADDITIONAL_ARGS)
|
||||
foreach(VAR ${PARSE_VARS})
|
||||
@ -47,6 +49,8 @@ function(add_sphinx_doc SRC_DIR)
|
||||
|
||||
add_custom_target(doc
|
||||
${SPHINX_EXECUTABLE}
|
||||
-j ${N}
|
||||
-n
|
||||
-b html
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
${ADDITIONAL_ARGS}
|
||||
|
@ -376,6 +376,8 @@ texinfo_documents = [
|
||||
#
|
||||
# texinfo_no_detailmenu = False
|
||||
|
||||
nitpicky = True
|
||||
|
||||
def insert_header(lines, f):
|
||||
for line in lines:
|
||||
yield line
|
||||
|
@ -1,3 +1,4 @@
|
||||
git+https://github.com/pfultz2/sphinx@develop
|
||||
sphinx>=1.5,<1.6
|
||||
# recommonmark==0.4.0
|
||||
git+https://github.com/pfultz2/recommonmark@develop
|
||||
sphinx-boost>0.0.2
|
||||
|
@ -46,7 +46,7 @@ Some parts of the documentation provides the meaning(or equivalence) of an expre
|
||||
Signatures
|
||||
----------
|
||||
|
||||
All the functions are global function objects except where an explicit template parameter is required. However, the documentation still shows the traditional signature since it is much clearer. So instead of writing this:
|
||||
All the functions are global function objects except where an explicit template parameter is required on older compilers. However, the documentation still shows the traditional signature since it is much clearer. So instead of writing this:
|
||||
|
||||
```cpp
|
||||
struct if_f
|
||||
|
@ -41,7 +41,7 @@ this:
|
||||
[](auto x) FIT_RETURNS(static_cast<std::ostringstream&>(std::ostringstream() << x).str())
|
||||
);
|
||||
|
||||
So, using [`FIT_RETURNS`](/include/fit/returns) not only deduces the return type for the function, but it also constrains the function on whether the expression is valid or not either. So by writing `FIT_RETURNS(std::to_string(x))` then the first function will try to call `std::to_string` function if possible. If not, then the second function will be called.
|
||||
So, using [`FIT_RETURNS`](/include/fit/returns) not only deduces the return type for the function, but it also constrains the function on whether the expression is valid or not. So by writing `FIT_RETURNS(std::to_string(x))` then the first function will try to call `std::to_string` function if possible. If not, then the second function will be called.
|
||||
|
||||
The second function still uses [`FIT_RETURNS`](/include/fit/returns), so the function will still be constrained by whether the `<<` stream operator can be used. Although it may seem unnecessary because there is not another function, however, this makes the function composable. So we could use this to define a `serialize` function that tries to call `stringify` first, otherwise it looks for the member `.serialize()`:
|
||||
|
||||
@ -54,20 +54,20 @@ static_if
|
||||
---------
|
||||
|
||||
In addition, this can be used with the [`fit::if_`](/include/fit/if) decorator to create `static_if`-like
|
||||
constructs. For example, Baptiste Wicht discusses how one could write `static_if` in C++ [here](http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html).
|
||||
constructs on pre-C++17 compilers. For example, Baptiste Wicht discusses how one could write `static_if` in C++ [here](http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html).
|
||||
|
||||
He wants to be able to write this:
|
||||
|
||||
template<typename T>
|
||||
void decrement_kindof(T& value){
|
||||
static_if(std::is_same<std::string, T>::value){
|
||||
if constexpr(std::is_same<std::string, T>()){
|
||||
value.pop_back();
|
||||
} else {
|
||||
--value;
|
||||
}
|
||||
}
|
||||
|
||||
However, that isn't possible in C++. With the Fit library one can simply write
|
||||
However, that isn't possible before C++17. With the Fit library one can simply write
|
||||
this:
|
||||
|
||||
template<typename T>
|
||||
|
@ -85,19 +85,16 @@ Now, this is useful for local functions. However, many times we want to write fu
|
||||
|
||||
FIT_STATIC_FUNCTION(sum) = sum_f();
|
||||
|
||||
The [`FIT_STATIC_FUNCTION`](/include/fit/function) declares a global variable following the best practices as outlined in [N4381](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html). This includes using `const` to avoid global state, compile-time initialization of the function object to avoid the [static initialization order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order), and an external address of the function object that is the same across translation units to avoid possible One-Definition-Rule(ODR) violations. In C++14, this can also be achieved by using a reference to a template variable:
|
||||
The [`FIT_STATIC_FUNCTION`](/include/fit/function) declares a global variable following the best practices as outlined in [N4381](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html). This includes using `const` to avoid global state, compile-time initialization of the function object to avoid the [static initialization order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order), and an external address of the function object that is the same across translation units to avoid possible One-Definition-Rule(ODR) violations. In C++17, this can be achieved using an `inline` variable:
|
||||
|
||||
template <class T>
|
||||
constexpr T static_function{};
|
||||
inline const constexpr auto sum = sum_f{};
|
||||
|
||||
static constexpr auto&& sum = static_function<sum_f>;
|
||||
|
||||
The [`FIT_STATIC_FUNCTION`](/include/fit/function) macro provides a portable way to do this that supports C++11 and MSVC, and allows supporting inline variables(in [N4424](http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4424.pdf)) in future versions of C++.
|
||||
The [`FIT_STATIC_FUNCTION`](/include/fit/function) macro provides a portable way to do this that supports pre-C++17 compilers and MSVC.
|
||||
|
||||
Adaptors
|
||||
--------
|
||||
|
||||
Now we have defined the function as a function object, we can add new "enhancements" to the function. One enhancement is to write "extension" methods. The proposal [N4165](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf) for Unified Call Syntax(UFCS) in C++17 would have allowed a function call of `x.f(y)` to become `f(x, y)`. Without UFCS in C++, we can instead use pipable function which would transform `x | f(y)` into `f(x, y)`. To make `sum_f` function pipable using the [`pipable`](/include/fit/pipable) adaptor, we can simply write:
|
||||
Now we have defined the function as a function object, we can add new "enhancements" to the function. One enhancement is to write "extension" methods. The proposal [N4165](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf) for Unified Call Syntax(UFCS) would have allowed a function call of `x.f(y)` to become `f(x, y)`. Without UFCS in C++, we can instead use pipable function which would transform `x | f(y)` into `f(x, y)`. To make `sum_f` function pipable using the [`pipable`](/include/fit/pipable) adaptor, we can simply write:
|
||||
|
||||
FIT_STATIC_FUNCTION(sum) = pipable(sum_f());
|
||||
|
||||
|
@ -31,7 +31,7 @@ Motivation
|
||||
Requirements
|
||||
============
|
||||
|
||||
This requires a C++11 compiler. There are no third-party dependencies. This has been tested on clang 3.5-3.8, gcc 4.6-6.2, and Visual Studio 2015. Gcc 5.1 is not supported at all, however, gcc 5.4 is supported.
|
||||
This requires a C++11 compiler. There are no third-party dependencies. This has been tested on clang 3.5-3.8, gcc 4.6-7, and Visual Studio 2015 and 2017.
|
||||
|
||||
Contexpr support
|
||||
----------------
|
||||
|
@ -69,7 +69,7 @@ It would be nice to write this:
|
||||
.transform([](int x) { return x * x; });
|
||||
|
||||
The proposal [N4165](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf)
|
||||
for Unified Call Syntax(UFCS) in C++17 would have allowed a function call of `x.f(y)` to become
|
||||
for Unified Call Syntax(UFCS) would have allowed a function call of `x.f(y)` to become
|
||||
`f(x, y)`. However, this was rejected by the comittee. So instead pipable functions can be
|
||||
used to achieve extension methods. So it can be written like this:
|
||||
|
||||
|
@ -1,20 +1,20 @@
|
||||
Partial function evaluation
|
||||
===========================
|
||||
|
||||
Many of the adaptors(such as [partial](partial) or [pipable](pipable)) in the library supports optional partial evaluation of functions. For example, if we have `sum` function adapted with `partial` adaptor:
|
||||
Many of the adaptors(such as [partial](partial) or [pipable](pipable)) in the library supports optional partial evaluation of functions. For example, if we have the `sum` function adapted with the `partial` adaptor:
|
||||
|
||||
auto sum = partial([](int x, int y)
|
||||
{
|
||||
return x+y;
|
||||
});
|
||||
|
||||
So if we write `sum(1, 2)` it will return 3, however, if we write `sum(1)` it will return a new function, which when called again it will evaluate the function and return 3:
|
||||
So if we write `sum(1, 2)` it will return 3, however, if we write `sum(1)` it will return a new function, which when called again, it will evaluate the function and return 3:
|
||||
|
||||
int i = sum(1, 2); // Returns 3
|
||||
auto f = sum(1);
|
||||
int j = f(2); // returns 3
|
||||
|
||||
Of course due to limitations in C++, to decide whether evaluate the function or to partially evaluated it is based on callability of the function and not arity. So if we call `sum(1, 2, 3)`, it will return a function:
|
||||
Of course due to limitations in C++, deciding whether evaluate the function or to partially evaluated it, is based on the callability of the function and not arity. So if we call `sum(1, 2, 3)`, it will return a function:
|
||||
|
||||
auto f = sum(1, 2, 3);
|
||||
|
||||
|
@ -14,10 +14,20 @@
|
||||
/// Description
|
||||
/// -----------
|
||||
///
|
||||
/// The `FIT_STATIC_FUNCTION` macro allows initializing a function object from
|
||||
/// a `constexpr` expression. It also ensures that the function object will
|
||||
/// have a unique address across translation units. This helps to avoid ODR
|
||||
/// violations. As such, the object that is deduced is default constructed.
|
||||
|
||||
/// The `FIT_STATIC_FUNCTION` macro allows initializing a function object from a
|
||||
/// `constexpr` expression. It uses the best practices as outlined in
|
||||
/// [N4381](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html).
|
||||
/// This includes using `const` to avoid global state, compile-time
|
||||
/// initialization of the function object to avoid the [static initialization
|
||||
/// order fiasco](https://isocpp.org/wiki/faq/ctors#static-init-order), and an
|
||||
/// external address of the function object that is the same across translation
|
||||
/// units to avoid possible One-Definition-Rule(ODR) violations.
|
||||
///
|
||||
/// In C++17, this achieved using the `inline` keyword. However, on older
|
||||
/// compilers it is initialized using a reference to a static member variable.
|
||||
/// The static member variable is default constructed, as such the user variable
|
||||
/// is always default constructed regardless of the expression.
|
||||
///
|
||||
/// By default, all functions defined with `FIT_STATIC_FUNCTION` use the
|
||||
/// [`fit::reveal`](/include/fit/reveal) adaptor to improve error messages.
|
||||
|
Loading…
Reference in New Issue
Block a user