This function generates a write function for graph entity properties.
The generated lambda function can then be called on each write specification in the adaptor tuple. It writes the specified data to a new dataset and adds attributes, fire-and-forget. Depending on the shape of the write specifications 1d or 2d datasets are written, see Utopia::DataIO::save_graph_entity_properties for more detail. Only relying on the given iterator pair, this function allows to handle vertex and edge iterations equivalently.
  139{
  140    static_assert(entity_kind == EntityKind::vertex or
  141                  entity_kind == EntityKind::edge,
  142                  "Error, 'entity_kind' has to be either 'vertex' or 'edge'");
  143 
  144    return
  145        [&g,
  146         nw_grp{std::forward<NWGroup>(nw_grp)},
  147         label{std::move(label)},
  148         it_pair{std::forward<ItPair>(it_pair)},
  149         num_entities{std::move(num_entities)}] (auto&& write_spec)
  150        
  151        
  152        {
  153 
  154        std::string prop_prefix;
  155 
  156        if constexpr (entity_kind == EntityKind::vertex) {
  157            prop_prefix = "vertex";
  158        }
  159        else {
  160            prop_prefix = "edge";
  161        }
  162 
  163        const auto grp =
  164            nw_grp->open_group(std::get<0>(write_spec));
  165 
  166        
  167        
  168        
  169        if constexpr (Utils::is_callable_v<std::tuple_element_t<1, 
  170                                    std::decay_t<decltype(write_spec)>>>)
  171        {
  172            const auto dset = grp->open_dataset(label, { num_entities });
  173 
  174            dset->write(it_pair.first, it_pair.second,
  175                [&](auto&& desc) {
  176                    return std::get<1>(write_spec)(desc, g);
  177                }
  178            );
  179 
  180            dset->add_attribute("dim_name__0", prop_prefix + "_idx");
  181            dset->add_attribute("coords_mode__"s + prop_prefix + "_idx",
  182                                "trivial");
  183        }
  184 
  185        
  186        
  187        
  188        
  189        else {
  190 
  191            static_assert(Utils::is_string_v<std::tuple_element_t<1,
  192                                    std::decay_t<decltype(write_spec)>>>,
  193                          "Error, the name of dimension 0 has to be s string");
  194 
  195            
  196            const auto adaptor_pairs = 
tuple_tail(write_spec);
 
  197            
  198            
  199 
  200            
  201            constexpr auto num_adaptors = std::tuple_size_v<std::decay_t<
  202                                                    decltype(adaptor_pairs)>>;
  203 
  204            
  205            const auto dset = grp->open_dataset(label,
  206                                                {num_adaptors, num_entities});
  207 
  208            
  209            using WriteSpecT = std::decay_t<decltype(write_spec)>;
  210            using FirstTupElementT = std::tuple_element_t<2, WriteSpecT>;
  211            using CoordT = std::tuple_element_t<0, FirstTupElementT>;
  212 
  213            
  214            auto coords = coords_container<CoordT>();
  215 
  216            
  217            
  218            auto apply_adaptor = [&](auto&& adaptor_pair){
  219                
  220                dset->write(it_pair.first, it_pair.second,
  221                    [&](auto&& desc) {
  222                        return std::get<1>(adaptor_pair)(desc, g);
  223                    }
  224                );
  225 
  226                static_assert(
  227                    
  228                    std::is_same_v<
  229                            std::tuple_element_t<0,
  230                                    std::decay_t<decltype(adaptor_pair)>>,
  231                            CoordT>,
  232                    "Error, coordinate types do not match! Check that all "
  233                    "coordinates are of the same type");
  234 
  235                coords.push_back(std::get<0>(adaptor_pair));
  236            };
  237 
  238            boost::hana::for_each(adaptor_pairs, apply_adaptor);
  239 
  240            
  241            const std::string dim0_name = std::get<1>(write_spec);
  242 
  243            
  244            dset->add_attribute("dim_name__0", dim0_name);
  245            dset->add_attribute("coords_mode__"s + dim0_name, "values");
  246            dset->add_attribute("coords__"s + dim0_name, coords);
  247 
  248            dset->add_attribute("dim_name__1", prop_prefix + "_idx");
  249            dset->add_attribute("coords_mode__"s + prop_prefix + "_idx",
  250                                "trivial");
  251        }
  252    };
  253}
constexpr std::tuple< Tail... > tuple_tail(const std::tuple< First, Second, Tail... > &t)
Builds new tuple containing all elements but the first two.
Definition graph_utils.hh:81