Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:58

0001 /*!
0002 @file
0003 Forward declares `boost::hana::Struct`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FWD_CONCEPT_STRUCT_HPP
0011 #define BOOST_HANA_FWD_CONCEPT_STRUCT_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 
0015 
0016 namespace boost { namespace hana {
0017     //! @ingroup group-concepts
0018     //! @defgroup group-Struct Struct
0019     //! The `Struct` concept represents `struct`-like user-defined types.
0020     //!
0021     //! The `Struct` concept allows restricted compile-time reflection over
0022     //! user-defined types. In particular, it allows accessing the names of
0023     //! the members of a user-defined type, and also the value of those
0024     //! members. `Struct`s can also be folded, searched and converted to
0025     //! some types of containers, where more advanced transformations can
0026     //! be performed.
0027     //!
0028     //! While all types can _in theory_ be made `Struct`s, only a subset of
0029     //! them are actually interesting to see as such. More precisely, it is
0030     //! only interesting to make a type a `Struct` when it is conceptually
0031     //! a C++ `struct`, i.e. a mostly dumb aggregate of named data. The way
0032     //! this data is accessed is mostly unimportant to the `Struct` concept;
0033     //! it could be through getters and setters, through public members,
0034     //! through non-member functions or it could even be generated on-the-fly.
0035     //! The important part, which is made precise below, is that those accessor
0036     //! methods should be move-independent.
0037     //!
0038     //! Another way to see a `Struct` is as a map where the keys are the names
0039     //! of the members and the values are the values of those members. However,
0040     //! there are subtle differences like the fact that one can't add a member
0041     //! to a `Struct`, and also that the order of the members inside a `Struct`
0042     //! plays a role in determining the equality of `Struct`s, which is not
0043     //! the case for maps.
0044     //!
0045     //!
0046     //! Minimal complete definition
0047     //! ---------------------------
0048     //! `accessors`
0049     //!
0050     //! A model of `Struct` is created by specifying a sequence of key/value
0051     //! pairs with the `accessors` function. The first element of a pair in
0052     //! this sequence represents the "name" of a member of the `Struct`, while
0053     //! the second element is a function which retrieves this member from an
0054     //! object. The "names" do not have to be in any special form; they just
0055     //! have to be compile-time `Comparable`. For example, it is common to
0056     //! provide "names" that are `hana::string`s representing the actual names
0057     //! of the members, but one could provide `hana::integral_constant`s just
0058     //! as well. The values must be functions which, when given an object,
0059     //! retrieve the appropriate member from it.
0060     //!
0061     //! There are several ways of providing the `accessors` method, some of
0062     //! which are more flexible and others which are more convenient. First,
0063     //! one can define it through tag-dispatching, as usual.
0064     //! @snippet example/struct.mcd.tag_dispatching.cpp main
0065     //!
0066     //! Secondly, it is possible to provide a nested `hana_accessors_impl`
0067     //! type, which should be equivalent to a specialization of
0068     //! `accessors_impl` for tag-dispatching. However, for a type `S`, this
0069     //! technique only works when the data type of `S` is `S` itself, which
0070     //! is the case unless you explicitly asked for something else.
0071     //! @snippet example/struct.mcd.nested.cpp main
0072     //!
0073     //! Finally, the most convenient (but least flexible) option is to use
0074     //! the `BOOST_HANA_DEFINE_STRUCT`, the `BOOST_HANA_ADAPT_STRUCT` or the
0075     //! `BOOST_HANA_ADAPT_ADT` macro, which provide a minimal syntactic
0076     //! overhead. See the documentation of these macros for details on how
0077     //! to use them.
0078     //!
0079     //! Also note that it is not important that the accessor functions retrieve
0080     //! an actual member of the struct (e.g. `x.member`). Indeed, an accessor
0081     //! function could call a custom getter or even compute the value of the
0082     //! member on the fly:
0083     //! @snippet example/struct.custom_accessor.cpp main
0084     //!
0085     //! The only important thing is that the accessor functions are
0086     //! move-independent, a notion which is defined below.
0087     //!
0088     //!
0089     //! @anchor move-independence
0090     //! Move-independence
0091     //! -----------------
0092     //! The notion of move-independence presented here defines rigorously
0093     //! when it is legitimate to "double-move" from an object.
0094     //!
0095     //! A collection of functions `f1, ..., fn` sharing the same domain is
0096     //! said to be _move-independent_ if for every fresh (not moved-from)
0097     //! object `x` in the domain, any permutation of the following statements
0098     //! is valid and leaves the `zk` objects in a fresh (not moved-from) state:
0099     //! @code
0100     //!     auto z1 = f1(std::move(x));
0101     //!     ...
0102     //!     auto zn = fn(std::move(x));
0103     //! @endcode
0104     //!
0105     //! @note
0106     //! In the special case where some functions return objects that can't be
0107     //! bound to with `auto zk =` (like `void` or a non-movable, non-copyable
0108     //! type), just pretend the return value is ignored.
0109     //!
0110     //! Intuitively, this ensures that we can treat `f1, ..., fn` as
0111     //! "accessors" that decompose `x` into independent subobjects, and
0112     //! that do so without moving from `x` more than that subobject. This
0113     //! is important because it allows us to optimally decompose `Struct`s
0114     //! into their subparts inside the library.
0115     //!
0116     //!
0117     //! Laws
0118     //! ----
0119     //! For any `Struct` `S`, the accessors in the `accessors<S>()` sequence
0120     //! must be move-independent, as defined above.
0121     //!
0122     //!
0123     //! Refined concepts
0124     //! ----------------
0125     //! 1. `Comparable` (free model)\n
0126     //! `Struct`s are required to be `Comparable`. Specifically, two `Struct`s
0127     //! of the same data type `S` must be equal if and only if all of their
0128     //! members are equal. By default, a model of `Comparable` doing just that
0129     //! is provided for models of `Struct`. In particular, note that the
0130     //! comparison of the members is made in the same order as they appear in
0131     //! the `hana::members` sequence.
0132     //! @include example/struct/comparable.cpp
0133     //!
0134     //! 2. `Foldable` (free model)\n
0135     //! A `Struct` can be folded by considering it as a list of pairs each
0136     //! containing the name of a member and the value associated to that
0137     //! member, in the same order as they appear in the `hana::members`
0138     //! sequence. By default, a model of `Foldable` doing just that is
0139     //! provided for models of the `Struct` concept.
0140     //! @include example/struct/foldable.cpp
0141     //! Being a model of `Foldable` makes it possible to turn a `Struct`
0142     //! into basically any `Sequence`, but also into a `hana::map` by simply
0143     //! using the `to<...>` function!
0144     //! @include example/struct/to.cpp
0145     //!
0146     //! 3. `Searchable` (free model)\n
0147     //! A `Struct` can be searched by considering it as a map where the keys
0148     //! are the names of the members of the `Struct`, and the values are the
0149     //! members associated to those names. By default, a model of `Searchable`
0150     //! is provided for any model of the `Struct` concept.
0151     //! @include example/struct/searchable.cpp
0152     template <typename S>
0153     struct Struct;
0154 }} // end namespace boost::hana
0155 
0156 #endif // !BOOST_HANA_FWD_CONCEPT_STRUCT_HPP