Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.Hana: Struct

Boost , ,

Boost.Hana  1.0.1
Your standard library for metaprogramming
Понятие<Struct>представляет<struct>Типы, определяемые пользователем.

Концепция<Struct>допускает ограниченное отражение времени компиляции по определенным пользователям типам. В частности, он позволяет получить доступ к именам членов определенного пользователем типа, а также к значению этих членов.<Struct>s также можно складывать, искать и преобразовывать в некоторые типы контейнеров, где могут быть выполнены более совершенные преобразования.

В то время как все типыв теориимогут быть сделаны<Struct>s, только подмножество из них действительно интересно рассматривать как таковые. Точнее, сделать тип a<Struct>интересно только тогда, когда он концептуально является C++.<struct>, т.е. в основном тупая совокупность названных данных. Способ доступа к этим данным в основном не имеет значения для концепции<Struct>; это может быть через геттеров и сеттеров, через публичных членов, через функции, не являющиеся членами, или это может даже генерироваться на лету. Важной частью, которая уточняется ниже, является то, что эти методы доступа должны быть независимыми от движения.

Другой способ увидеть<Struct>— это карта, где ключи — имена членов, а значения — ценности этих членов. Тем не менее, есть тонкие различия, такие как тот факт, что нельзя добавить члена к<Struct>, а также то, что порядок членов внутри<Struct>играет роль в определении равенства<Struct>, что не относится к картам.

Minimal complete definition

<accessors>

Модель<Struct>создается путем указания последовательности пар ключ/значение с функцией<accessors>. Первый элемент пары в этой последовательности представляет собой «имя» члена<Struct>, в то время как второй элемент является функцией, которая извлекает этот элемент из объекта. «Имена» не должны быть в какой-либо особой форме; они просто должны быть составлены<Comparable>. Например, обычно предоставляются «имена», которые<hana::string>представляют фактические имена членов, но можно также предоставить<hana::integral_constant>. Значения должны быть функциями, которые при получении объекта извлекают из него соответствующий элемент.

Существует несколько способов предоставления метода<accessors>, некоторые из которых более гибкие, а другие более удобные. Во-первых, его можно определить с помощью диспетчеризации тегов, как обычно.

struct Person {
std::string name;
int age;
};
// The keys can be anything as long as they are compile-time comparable.
constexpr auto name = hana::integral_c<std::string Person::*, &Person::name>;
constexpr auto age = hana::string_c<'a', 'g', 'e'>;
namespace boost { namespace hana {
template <>
struct accessors_impl<Person> {
static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
return make_tuple(
make_pair(name, [](auto&& p) -> decltype(auto) {
return id(std::forward<decltype(p)>(p).name);
}),
make_pair(age, [](auto&& p) -> decltype(auto) {
return id(std::forward<decltype(p)>(p).age);
})
);
}
};
}}

Во-вторых, можно обеспечить вложенный<hana_accessors_impl>тип, который должен быть эквивалентен специализации<accessors_impl>для диспетчеризации меток. Однако для типа<S>этот метод работает только тогда, когда тип данных<S>сам по себе<S>, что имеет место, если вы явно не просили что-то другое.

struct Person {
std::string name;
int age;
struct hana_accessors_impl {
static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
return boost::hana::make_tuple(
boost::hana::make_pair(BOOST_HANA_STRING("name"),
[](auto&& p) -> decltype(auto) {
return boost::hana::id(std::forward<decltype(p)>(p).name);
}),
boost::hana::make_pair(BOOST_HANA_STRING("age"),
[](auto&& p) -> decltype(auto) {
return boost::hana::id(std::forward<decltype(p)>(p).age);
})
);
}
};
};

Наконец, наиболее удобным (но наименее гибким) вариантом является использование макроса<BOOST_HANA_DEFINE_STRUCT>,<BOOST_HANA_ADAPT_STRUCT>или<BOOST_HANA_ADAPT_ADT>, которые обеспечивают минимальные синтаксические накладные расходы. Посмотрите документацию этих макросов для получения подробной информации о том, как их использовать.

Также обратите внимание, что не важно, чтобы функции доступа извлекали фактический элемент структуры (например,<x.member>). Действительно, функция доступа может вызвать пользовательский геттер или даже вычислить значение члена на лету:

struct Person {
Person(std::string const& name, int age) : name_(name), age_(age) { }
std::string const& get_name() const { return name_; }
int get_age() const { return age_; }
private:
std::string name_;
int age_;
};
namespace boost { namespace hana {
template <>
struct accessors_impl<Person> {
static BOOST_HANA_CONSTEXPR_LAMBDA auto apply() {
return make_tuple(
make_pair(BOOST_HANA_STRING("name"), [](auto&& p) -> std::string const& {
return p.get_name();
}),
make_pair(BOOST_HANA_STRING("age"), [](auto&& p) {
return p.get_age();
})
);
}
};
}}

Единственное, что важно, это то, что функции доступа являются независимыми от движения, понятие, которое определено ниже.

Move-independence

Представленное здесь понятие независимости движения строго определяет, когда законно «двойное движение» от объекта.

Коллекция функций<f1, ..., fn>, совместно использующих один и тот же домен, называетсядвижущейся независимой, если для каждого свежего (не перемещенного) объекта<x>в домене действует любая перестановка следующих утверждений и оставляет<zk>объекты в свежем (не перемещенном) состоянии:

auto z1 = f1(std::move(x));
...
auto zn = fn(std::move(x));
Note
In the special case where some functions return objects that can't be bound to with auto zk = (like void or a non-movable, non-copyable type), just pretend the return value is ignored.

Интуитивно это гарантирует, что мы можем рассматривать<f1, ..., fn>как «присоединителей», которые разлагаются<x>на независимые подобъекты, и которые делают это, не переходя от<x>больше, чем этот подобъект. Это важно, поскольку позволяет оптимально разложить<Struct>с на их подчасти внутри библиотеки.

Laws

Для любого<Struct><S>аксессуары в последовательности<accessors<S>()>должны быть независимыми от движения, как определено выше.

Refined concepts

  1. Comparable(бесплатная модель)
    StructComparable[Comparable]. В частности, дваStructс одного и того же типа данныхSдолжны быть равны, если и только если все их члены равны. По умолчанию модельComparableделает именно то, что предусмотрено для моделейStruct. В частности, обратите внимание, что сравнение членов производится в том же порядке, в каком они появляются в последовательностиhana::members.
    // Авторское право Louis Dionne 2013-2016
    // Распространяется по лицензии Boost Software, версия 1.0.
    // [См. сопроводительный файл LICENSE.md или копия по адресу http://boost.org/LICENSE_1_0.txt]
    #include<]
    #include<]
    [hana/equal.hpp>]
    #include<]
    [hana/keys.hpp>]
    [Лицо
    [лицо,
    [std::string, name]
    коротко
    , возраст]
    [ORIG_END] -->
  2. Foldable(свободная модель)
    AStructможно сложить, рассматривая его как список пар, каждая из которых содержит имя члена и значение, связанное с этим членом, в том же порядке, в котором они появляются вhana::membersпоследовательности. По умолчанию модельFoldableделает именно то, что предусмотрено для моделейStructконцепта.
    // Авторское право Louis Dionne 2013-2016
    // Распространяется по лицензии Boost Software License, Version 1.0.
    // (См. сопроводительный файл LICENSE.md или копия по адресу http://boost.org/LICENSE_1_0.txt)
    FoldableSequence#include<>
    Sequence#include<boost/hana/define_struct.hpp>#include<boost/hana/fold_left.hpp>boost/hana/second.hpp>]
    [Классный класс]
    Boost_HANA_DEFINE_STRUCT(Классная,
    [неподписаннаякороткаякороткаякороткая
    , девочки]
    intmain()
    constexpr Classroom compsci [20, 3];
    возврат[24 Будучи модельюFoldable, можно превратитьStructв в основном любойSequence, но также и вhana::map, просто используя функциюto<...>!
    // Авторское право Louis Dionne 2013-2016
    // Распространяется по лицензии Boost Software License, Version 1.0.
    // [См. сопроводительный файл LICENSE.md или копия по http://boost.org/LICENSE_1_0.txt]
    SequenceSequence>
    >
    Sequence
    Sequence
    (std::string, name),
    короткий, возраст]
    ]
    intmain()
    hana::map"John", 30u];
    BOOST_HANA_RUNTIME_CHECK(hana::to(john) == hana::make_map(
    hana::make_pair("name"),"John"],
    ]
    ] Being a model of Foldable makes it possible to turn a Struct into basically any Sequence, but also into a hana::map by simply using the to<...> function!
    // Copyright Louis Dionne 2013-2016
    // Distributed under the Boost Software License, Version 1.0.
    // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    #include <string>
    namespace hana = boost::hana;
    struct Person {
    (std::string, name),
    (unsigned short, age)
    );
    };
    int main() {
    Person john{"John", 30u};
    BOOST_HANA_RUNTIME_CHECK(hana::to<hana::map_tag>(john) == hana::make_map(
    hana::make_pair(BOOST_HANA_STRING("name"), "John"),
    hana::make_pair(BOOST_HANA_STRING("age"), 30u)
    ));
    }
    [ORIG_END] -->
  3. Searchable(бесплатная модель)
    AStructможно искать, рассматривая его как карту, где ключи являются именами членовStruct, а значения - членами, связанными с этими именами. По умолчанию модельSearchableпредусмотрена для любой модели концепцииStruct.
    // Авторское право Louis Dionne 2013-2016
    // Распространяется по лицензии Boost Software License, версия 1.0.
    // [См. сопроводительный файл LICENSE.md или копию по адресу http://boost.org/LICENSE_1_0.txt]
    >
    #include<
    [ BOOST_HANA_DEFINE_STRUCT(Лицо,
    (std::string, name),
    неподписанноекороткое, возраст]
    ;
    ];
    intmain()
    Человек Джон"John", 30];
    hana::find(john, BOOST_HANA_STRING"name") == hana: just"John")
    ;
    BOOST_HANA_CONSTANT_CHECK
    hana::find[john, BOOST_HANA_STRING"foobar"] == hana:: nothing
    ]
    [ORIG_END] -->

Functions

auto boost::hana::BOOST_HANA_ADAPT_ADT (...)
 Defines a model of Struct with the given accessors.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike BOOST_HANA_ADAPT_STRUCT, this macro requires specifying the way to retrieve each member by providing a function that does the extraction. More...
 
auto boost::hana::BOOST_HANA_ADAPT_STRUCT (...)
 Defines a model of Struct with the given members.Using this macro at global scope will define a model of the Struct concept for the given type. This can be used to easily adapt existing user-defined types in a ad-hoc manner. Unlike the BOOST_HANA_DEFINE_STRUCT macro, this macro does not require the types of the members to be specified. More...
 
auto boost::hana::BOOST_HANA_DEFINE_STRUCT (...)
 Defines members of a structure, while at the same time modeling Struct.Using this macro in the body of a user-defined type will define the given members inside that type, and will also provide a model of the Struct concept for that user-defined type. This macro is often the easiest way to define a model of the Struct concept. More...
 

Variables

template<typename S >
constexpr auto boost::hana::accessors
 Returns a Sequence of pairs representing the accessors of the data structure.Given a Struct S, accessors<S>() is a Sequence of Products where the first element of each pair is the "name" of a member of the Struct, and the second element of each pair is a function that can be used to access that member when given an object of the proper data type. As described in the global documentation for Struct, the accessor functions in this sequence must be move-independent. More...
 
constexpr keys_t boost::hana::keys {}
 Returns a Sequence containing the name of the members of the data structure.Given a Struct object, keys returns a Sequence containing the name of all the members of the Struct, in the same order as they appear in the accessors sequence. More...
 
constexpr auto boost::hana::members
 Returns a Sequence containing the members of a Struct.Given a Struct object, members returns a Sequence containing all the members of the Struct, in the same order as their respective accessor appears in the accessors sequence. More...
 

Function Documentation

auto boost::hana::BOOST_HANA_ADAPT_ADT (   ...)

<#include <boost/hana/fwd/adapt_adt.hpp>>

<Struct>, то есть в том виде, в каком он был. Использование этого макроса вглобальном масштабеопределит модель концепции<Struct>для данного типа. Это может быть использовано для легкой адаптации существующих типов, определенных пользователем, специальным образом. В отличие от<BOOST_HANA_ADAPT_STRUCT>, этот макрос требует указания способа извлечения каждого члена путем предоставления функции, которая выполняет извлечение.

Note
This macro only works if the tag of the user-defined type T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
namespace ns {
struct Person {
explicit Person(std::string const& name, int age)
: name_(name), age_(age)
{ }
std::string const& get_name() const { return name_; }
int get_age() const { return age_; }
private:
std::string name_;
int age_;
};
}
(name, [](ns::Person const& p) { return p.get_name(); }),
(age, [](ns::Person const& p) { return p.get_age(); })
);
// The member names are hana::strings:
auto names = hana::transform(hana::accessors<ns::Person>(), hana::first);
names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
);
int main() {
ns::Person john{"John", 30}, bob{"Bob", 40};
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
}
auto boost::hana::BOOST_HANA_ADAPT_STRUCT (   ...)

<#include <boost/hana/fwd/adapt_struct.hpp>>

В ней описана модель<Struct>. Использование этого макроса вглобальном масштабеопределит модель концепции<Struct>для данного типа. Это может быть использовано для легкой адаптации существующих типов, определенных пользователем, специальным образом. В отличие от<BOOST_HANA_DEFINE_STRUCT>макроса, этот макрос не требует указания типов членов.

Note
This macro only works if the tag of the user-defined type T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
namespace ns {
struct Person {
std::string name;
int age;
};
}
name,
age
);
// The member names are hana::strings:
auto names = hana::transform(hana::accessors<ns::Person>(), hana::first);
names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
);
int main() {
ns::Person john{"John", 30}, bob{"Bob", 40};
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
}
auto boost::hana::BOOST_HANA_DEFINE_STRUCT (   ...)

<#include <boost/hana/fwd/define_struct.hpp>>

Определение элементов структуры, в то же время моделирование<Struct>.Использование этого макроса в теле определяемого пользователем типа будет определять данные элементы внутри этого типа, а также обеспечит модель концепции<Struct>для этого определяемого пользователем типа. Этот макрос часто является самым простым способом определения модели концепции<Struct>.

Note
This macro only works if the tag of the user-defined type T is T itself. This is the case unless you specifically asked for something different; see tag_of's documentation.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
struct Person {
(std::string, name),
(int, age)
);
};
// The member names are hana::strings:
auto names = hana::transform(hana::accessors<Person>(), hana::first);
names == hana::make_tuple(BOOST_HANA_STRING("name"), BOOST_HANA_STRING("age"))
);
int main() {
Person john{"John", 30}, bob{"Bob", 40};
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("name")) == hana::just("John"));
BOOST_HANA_RUNTIME_CHECK(hana::find(john, BOOST_HANA_STRING("age")) == hana::just(30));
BOOST_HANA_CONSTANT_CHECK(hana::find(john, BOOST_HANA_STRING("foo")) == hana::nothing);
BOOST_HANA_RUNTIME_CHECK(hana::to_tuple(john) == hana::make_tuple(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
BOOST_HANA_RUNTIME_CHECK(hana::to_map(john) == hana::make_map(
hana::make_pair(BOOST_HANA_STRING("name"), "John"),
hana::make_pair(BOOST_HANA_STRING("age"), 30)
));
}

Variable Documentation

template<typename S >
constexpr auto boost::hana::accessors

<#include <boost/hana/fwd/accessors.hpp>>

Initial value:
= []() {
return tag-dispatched;
}

Возвращает<Sequence>пары, представляющие аксессуары структуры данных. Учитывая<Struct><S>,<accessors<S>()>является<Sequence>из<Product>с, где первым элементом каждой пары является «имя» члена<Struct>, а вторым элементом каждой пары является функция, которая может быть использована для доступа к этому элементу при предоставлении объекту соответствующего типа данных. Как описано в глобальной документации для<Struct>, функции доступа в этой последовательности должны быть независимыми от движения.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
struct Person {
(std::string, name),
(unsigned short, age)
);
};
int main() {
constexpr auto accessors = hana::accessors<Person>();
hana::first(accessors[hana::size_c<0>]) == BOOST_HANA_STRING("name")
);
hana::first(accessors[hana::size_c<1>]) == BOOST_HANA_STRING("age")
);
constexpr auto get_name = hana::second(accessors[hana::size_c<0>]);
constexpr auto get_age = hana::second(accessors[hana::size_c<1>]);
Person john{"John", 30};
BOOST_HANA_RUNTIME_CHECK(get_name(john) == "John");
BOOST_HANA_RUNTIME_CHECK(get_age(john) == 30);
}
constexpr auto boost::hana::keys {}
related

<#include <boost/hana/fwd/keys.hpp>>

Возвращает<Sequence>, содержащий имя членов структуры данных. При наличии<Struct>объекта<keys>возвращается<Sequence>, содержащий имя всех членов<Struct>, в том же порядке, в каком они появляются в<accessors>последовательности.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
struct Person {
(std::string, name),
(unsigned short, age)
);
};
int main() {
Person john{"John", 30};
hana::keys(john) == hana::make_tuple(BOOST_HANA_STRING("name"),
BOOST_HANA_STRING("age"))
);
}
constexpr auto boost::hana::members

<#include <boost/hana/fwd/members.hpp>>

Initial value:
= [](auto&& object) {
return tag-dispatched;
}

Возвращает<Sequence>, содержащий элементы<Struct>.Учитывая<Struct>объект,<members>возвращает<Sequence>, содержащий все члены<Struct>, в том же порядке, в котором их соответствующий аксессуар появляется в<accessors>последовательности.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
struct Person {
(std::string, name),
(unsigned short, age)
);
};
int main() {
Person john{"John", 30};
BOOST_HANA_RUNTIME_CHECK(hana::members(john) == hana::make_tuple("John", 30));
}

Статья Boost.Hana: Struct раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 20:47:44/0.01042103767395/0