2017-10-01

Straight Declarations C++ библиотека

Исторически сложившийся синтаксис объявлений в C++ крайне мутен. Спиральное правило и операторы, переиспользованные для объявления чего-нибудь, могут сделать объявления нечитаемыми вплоть до того, что люди начнут писать специальные сервисы для расшифровки. С недавним введением rvalue- и универсальных ссылок ситуация стала еще хуже.

Чтение объявлений в C++ меме.

Straight Declarations - это header-only C++11 библиотека, предоставляющая alias шаблоны для объявления массивов, указателей и ссылок с единообразным синтаксисом и ясной семантикой. Эта библиотека позволяет писать объявления с порядком чтения слева-направо и устраняет переиспользование символов *, &, [ и ]. Эта библиотека не нацелена на устранение промежуточных алиасов типов или сокращение длины объявлений (хотя это может иметь место в некоторых случаях).

Appveyor CI статус сборки. Travis CI статус сборки.

Загрузки for rev. 68

Mercurial (зеркало Bitbucket) clone:
hg clone https://bitbucket.org/guaranteed-to-be-unique/straight-declarations
Git (зеркало Github) clone:
git clone https://github.com/guaranteed-to-be-unique/straight-declarations.git

Примеры

// Declare this macro to enable lowercase, std-like syntax.

#define VTT_STRAIGHT_DECLARATIONS_ENABLE_STD_STYLE_SYNTAX

// Include main library header to bring everything into scope.

#include
<
vtt/Straight Declarations.hpp
>


// A C-style array of 3 ints.

int
items
[
3
];

vtt::
array
<
3
,
int
>
items
;


// A pointer to an int.

int
*
p
;

vtt::
ptr
<
int
>
p
;


// A pointer to a function taking nothing and returning an int.

int
( *
p_fun
)(
void
);

vtt::
ptr
<
auto
(
void
) ->
int
>
p_fun
;


// A pointer to a non-static foo_t class member item

// of const-qualified int type.

const
int
foo_t
::*
p_member
;

vtt::
ptr
<
foo_t
, const
int
>
p_member
;


// A pointer to a const-qualified non-static foo_t class

// member function taking nothing and returning an int.

int
(
foo_t
::*
p_member_fun
)(
void
) const;

vtt::
ptr
<const
foo_t
,
auto (
void
) ->
int
>
p_member_fun
;


// A function taking an rvalue reference to foo_t.

auto
action
(
foo_t
&&
foo
) ->
int
;

auto
action
(vtt::
rvalref
<
foo_t
>
foo
) ->
int
;


// A function template taking a universal reference to T.

// Looks the same as if bar was an rvalue reference.

template<typename
T
> auto
action
(
T
&&
bar
) ->
int
;

// Intentions are clear.

template<typename
T
> auto
action
(vtt::
uniref
<
T
>
bar
) ->
int
;


// We can also mix things together!


using namespace vtt;
// for convenience


// A reference to a C-style array of 4 chars.

char
( &
items
)[
4
];

ref
<
array
<
4
,
char
>>
items
;


// A pointer to a function taking nothing and returning

// a reference to a C-style array of 4 chars.

char
( & ( *
p_fun
)(
void
) )[
4
];

ptr
<auto (
void
) ->
ref
<
array
<
4
,
char
>>>
p_fun
;

Зависимости

Компилятор с хорошей поддержкой C++11. Протестированные компиляторы:

  • Visual C++: 14.0, 14.1
  • g++: 4.8.2, 4.9.4, 5.4.1, 6.3.0
  • clang++: 3.5.0, 3.9.1, 4.0.1

Тесты также используют boost 1.65.1 или новее (только заголовочные файлы), заголовочные файлы подразумеваются находящимися в директории ../boost. Контрольный скрипт memcheck.sh требует valgrind.

Известные проблемы

  • Сборка проектов посредством VS выдает предупреждение MSB8029: The Intermediate directory or Output directory cannot reside under the Temporary directory as it could lead to issues with incremental build.". Это предупреждение вызвано использованием $(TEMP) в качестве Intermediate директории. Ни один из проектов не использует инкрементальную сборку, так что это предупреждение можно спокойно игнорировать.
  • Сборка проекта с тестами выдает множество предупреждений из глубины Boost.Test. Хотя они, по большей части, безобидны, разработчикам boost надо бы взяться за ум.
  • VS успешно собирает тест Array_Of_ZeroItemsCompilationFailure.
  • VS выдает ошибки (включая ICE) при инстанцировании шаблона, когда среди его параметров имеется сигнатура функции, в качестве хвостового возвращаемого типа которой инстанцируется еще один шаблон. Например:

    ptr
    <auto (
    void
    ) ->
    ref
    <
    int
    >>
    p_fun
    ;
    Чтобы обойти эту проблему можно использовать головной возвращаемый тип.