Skip to content
Snippets Groups Projects
Commit e9926eca authored by Scott Snyder's avatar Scott Snyder Committed by Tadej Novak
Browse files

CxxUtils: Add releasing_iterator.

CxxUtils: Add releasing_iterator.

Helper to convert an iterator over unique_ptr<T> to one over T*.
parent 0371f0c9
No related branches found
No related tags found
No related merge requests found
......@@ -145,7 +145,8 @@ foreach( test sincos_test ArrayScanner_test Arrayrep_test
vec_int_test vec_float_test vec_fb_int_test vec_fb_float_test
ConcurrentHashmapImpl_test SimpleUpdater_test hexdump_test
FPControl_test LockedPointer_test nodiscard_test span_test
reverse_wrapper_test atomic_bounded_decrement_test )
reverse_wrapper_test atomic_bounded_decrement_test
releasing_iterator_test)
atlas_add_test( ${test}
SOURCES test/${test}.cxx
LINK_LIBRARIES CxxUtils TestTools )
......
// This file's extension implies that it's C, but it's really -*- C++ -*-.
/*
* Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
*/
/**
* @file CxxUtils/releasing_iterator.h
* @author scott snyder <snyder@bnl.gov>
* @date Feb, 2023
* @brief Adapter to retrieve elements from a unique_ptr iterator via release().
*/
#ifndef CXXUTILS_RELEASING_ITERATOR_H
#define CXXUTILS_RELEASING_ITERATOR_H
#include <iterator>
namespace CxxUtils {
/**
* @brief Adapter to retrieve elements from a unique_ptr iterator via release().
*
* This allows, say,
*@code
* std::vector<std::unique_ptr<Foo> > c1 = ...;
* std::vector<Foo*> c2;
* c2.assign (releasing_iterator(c1.begin()), releasing_iterator(c1.end()));
@endcode
*
* All elements in @c c1 will be release'd.
*
* Since this implies that a given iterator can only be dereferenced once,
* this iterator models @c input_iterator.
*/
template <class ITERATOR>
class releasing_iterator
{
public:
using value_type = typename std::iterator_traits<ITERATOR>::value_type::pointer;
using reference = value_type&;
using pointer = value_type*;
using difference_type = typename std::iterator_traits<ITERATOR>::difference_type;
using iterator_category = std::input_iterator_tag;
releasing_iterator (ITERATOR it) : m_it (it) {}
value_type operator*() { return m_it->release(); }
releasing_iterator& operator++() { ++m_it; return *this; }
bool operator!= (const releasing_iterator& other) const { return m_it != other.m_it; }
private:
ITERATOR m_it;
};
} // namespace CxxUtils
#endif // not CXXUTILS_RELEASING_ITERATOR_H
CxxUtils/releasing_iterator
test1
/*
* Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration.
*/
/**
* @file CxxUtils/releasing_iterator_test.h
* @author scott snyder <snyder@bnl.gov>
* @date Jan, 2023
* @brief Unit tests for releasing_iterator.
*/
#undef NDEBUG
#include "CxxUtils/releasing_iterator.h"
#include <memory>
#include <vector>
#include <iostream>
#include <cassert>
void test1()
{
std::cout << "test1\n";
std::vector<std::unique_ptr<int> > v1;
for (int i = 0; i < 10; i++) {
v1.emplace_back (std::make_unique<int>(i));
}
using CxxUtils::releasing_iterator;
std::vector<int* > v2 (releasing_iterator(v1.begin()),
releasing_iterator(v1.end()));
assert (v1.size() == 10);
assert (v2.size() == 10);
for (int i = 0; i < 10; i++) {
assert (!v1[i]);
assert (*v2[i] == i);
delete v2[i];
}
}
int main()
{
std::cout << "CxxUtils/releasing_iterator\n";
test1();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment