28    rapidjson::Document json{};
 
   34        if (not json.HasMember(osc_path_v<T, Components>)) 
return;
 
   35        auto& m = json[osc_path_v<T, Components>];
 
   38            if constexpr (std::integral<value_t<T>>)
 
   40                if constexpr (std::is_signed_v<value_t<T>>)
 
   42                         if (m.IsInt())   f(m.GetInt());
 
   43                    else if (m.IsInt64()) f(m.GetInt64());
 
   46                         if (m.IsUint())   f(m.GetUint());
 
   47                    else if (m.IsUint64()) f(m.GetUint64());
 
   49            } 
else if constexpr (std::floating_point<value_t<T>>)
 
   51                if (m.IsDouble()) f(
static_cast<value_t<T>
>(m.GetDouble()));
 
   54                if (m.IsString()) f(m.GetString());
 
   57                if (!m.IsArray() || m.Empty() || m.Size() != size<value_t<T>>()) 
return;
 
   58                if constexpr (std::integral<element_t<T>>)
 
   61                        f(m, [](
auto& arr, 
auto idx) { 
return arr[idx].GetInt(); });
 
   62                    else if (m[0].IsInt64())
 
   63                        f(m, [](
auto& arr, 
auto idx) { 
return arr[idx].GetInt64(); });
 
   64                } 
else if constexpr (std::floating_point<element_t<T>>)
 
   67                        f(m, [](
auto& arr, 
auto idx) { 
return arr[idx].GetDouble(); });
 
   71                        f(m, [](
auto& arr, 
auto idx) { 
return arr[idx].GetString(); });
 
 
   77    void init(IStream& istream, Components& components)
 
   79        json.ParseStream(istream);
 
   80        if (not json.IsObject())
 
   85        for_each_session_datum(components, [&]<
typename T>(T& endpoint)
 
   88                apply_with_json_member_value<T>(json, [&](
auto& arr, 
auto&& get)
 
   90                for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
 
   91                    value_of(endpoint)[i] = get(arr, i);
 
   93            else apply_with_json_member_value<T>(json, [&](
auto value)
 
   95                set_value(endpoint, value);
 
  101    void external_destinations(Components& components)
 
  103        bool updated = 
false;
 
  104        for_each_session_datum(components, [&]<
typename T>(T& endpoint)
 
  106            if constexpr (has_value<T>)
 
  108                if (not json.HasMember(osc_path_v<T, Components>))
 
  110                    if constexpr (string_like<value_t<T>>)
 
  112                        rapidjson::Value v{value_of(endpoint).c_str(), json.GetAllocator()};
 
  113                        json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, v, json.GetAllocator());
 
  115                    else if constexpr (array_like<value_t<T>>)
 
  117                        rapidjson::Value v{rapidjson::kArrayType};
 
  118                        v.Reserve(3, json.GetAllocator());
 
  119                        for (
auto& element : value_of(endpoint)) v.PushBack(rapidjson::Value{element}, json.GetAllocator());
 
  120                        json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, v, json.GetAllocator());
 
  124                        json.AddMember(rapidjson::GenericStringRef{osc_path_v<T, Components>}, value_of(endpoint), json.GetAllocator());
 
  130                    bool endpoint_updated = 
false;
 
  131                    if constexpr (OccasionalValue<T>)
 
  132                        endpoint_updated = flag_state_of(endpoint);
 
  133                    else if constexpr (array_like<value_t<T>>)
 
  134                        apply_with_json_member_value<T>(json, [&](
auto& arr, 
auto&& get)
 
  136                        for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
 
  137                            endpoint_updated = endpoint_updated || (value_of(endpoint)[i] != get(arr, i));
 
  139                    else apply_with_json_member_value<T>(json, [&](
auto value)
 
  141                        endpoint_updated = value != value_of(endpoint);
 
  143                    if (endpoint_updated)
 
  145                        if constexpr (string_like<value_t<T>>)
 
  146                            json[osc_path_v<T, Components>].SetString(value_of(endpoint).c_str(), json.GetAllocator());
 
  147                        else if constexpr (array_like<value_t<T>>)
 
  149                            auto& arr = json[osc_path_v<T, Components>];
 
  150                            for (std::size_t i = 0; i < size<value_t<T>>(); ++i)
 
  152                                arr[i] = value_of(endpoint)[i];
 
  155                        else json[osc_path_v<T, Components>] = value_of(endpoint);
 
  164            json.Accept(ostream.writer);