#include "cleantype_examples_utils.h"
#include "types_variations.hpp"
#include <fplus/fplus.hpp>
using namespace types_variations;
In my opinion, the "east-const" vs "west-const" debate is just the tip of the iceberg. It is a sign that we would need additional "spelling conventions" as far as the types are concerned. Those rules might not be required for a successful compilation, but they should exist nonetheless.
In written english, the spelling rules say for example that each comma (",") should be followed by exactly one space (etc.), as well as each question mark ("?"), etc.
it is still possible to Write a sentence ,and to ignore totally those rules ;but it is considered Ugly -and rightfuly so - !
Below are some examples:
I do not think there is an established convention about the spacing of the types (apart from the fact the C++ Core Guideline advise to uses spaces sparingly). An established convention (even if not enforced by the compiler) would be welcome.
How many possible spellings for vector<map<char **, int>>
? There is a whopping number of possibilities: 1024!
{
std::string type1 = "vector<map<char**,int>>";
auto l = space_variations(type1);
std::cout << show_type_string_list(l);
}
Below is the cursed const T * const
vs T const * const
example.
My personal preference goes to const int * const
(i.e spaces everywhere, and the "const" keyword is kept close to what is const).
However, who cares about my personal preference?
I do not even care that much!
I would strongly prefer to have an established convention to which I could refer.
{
auto f = combine_transforms(add_const_ptr_const, space_variations);
std::cout << show_type_string_list(f("int"));
}
In C++, the struct
(or class
) keywords can be ellided.
However, MSVC chose to not ellide them in its typeid
implementation, so that for const Foo &
we have the following possibilities:
{
auto f = combine_transforms(
compiler_maybe_add_struct, add_const_ref, space_variations);
std::cout << show_type_string_list(f("Foo"));
}
Compilers and libc implementations add their dose of complexity to the mix, since they add synonyms to the std
namespace (std::__1::
or std::__cxx11::
) and Visual Studio can modify pointer types by adding __ptr64
or __ptr32
, whenever the compilation is done in 64 bits.
Let's examine the possible spellings of std::vector<const char *>
by different compilers and/or different libc implementations:
{
auto f = combine_transforms(
compiler_maybe_add_ptr64, add_const, add_vector, compiler_maybe_add_std_namespace);
std::cout << show_type_string_list(f("char"));
}
When types become more complex, an indentation quickly becomes needed. An established convention on how to indent them would also be worthwile. Subjects like "when to start indenting" (after 2 or 3 nested levels for example), and how to indent are interesting subjects to be adressed.
One possible way to indent type could state that
join_view<transform_view<iota_view<int, void>, single_view<int> (*)(int)>, void> &
should be indented like this:
join_view<
transform_view<
iota_view<
int,
void
>,
single_view<
int
> (*)(int)
>,
void
> &
This indentation style is the default indentation style provided by CleanType
All the previous examples mentioned types spellings that are exact synonyms, i.e they denote exactly the same type.
However in C++, there are also close synomyms with the afore mentioned qualifiers. They are a different subject, and for example the Boost CallableTraits manual gives a complete list of the possible variations for callable functions.