inline void setValue(tinyxml2::XMLElement& elt, const TaskTimer& timer) {
    elt.DeleteChildren();

    auto taskDurations = computeTaskDurations<Microseconds>(timer);
    auto totalTime = std::accumulate(begin(taskDurations), end(taskDurations), Microseconds(0), std::plus<Microseconds>());
    setChildAttribute(elt, "TotalTime", totalTime);
    for(auto taskID: range(timer.getTaskCount())) {
        auto percentage = 100. * taskDurations[taskID].count() / totalTime.count();
        auto pChildElement = setChildAttribute(elt, timer.getTaskName(taskID).c_str(), taskDurations[taskID]);
        setAttribute(*pChildElement, "percentage", percentage);
    }
}
inline void setValue(tinyxml2::XMLElement& elt, const std::vector<T>& values) {
    elt.DeleteChildren();
    for(const auto& i: range(size(values))) {
        setChildAttribute(elt, (std::string("v") + toString(i)).c_str(), values[i]);
    }
}
inline void setValue(tinyxml2::XMLElement& elt, const Microseconds& microseconds) {
    elt.DeleteChildren();
    setChildAttribute(elt, "Microseconds", microseconds.count());
    setChildAttribute(elt, "Milliseconds", us2ms(microseconds));
    setChildAttribute(elt, "Seconds", us2sec(microseconds));
}
inline void setValue(tinyxml2::XMLElement& elt, const std::unordered_map<std::string, T>& values) {
    elt.DeleteChildren();
    for(const auto& pair: values) {
        setChildAttribute(elt, pair.first.c_str(), pair.second);
    }
}