Refactor "get only from iterator" to a utility.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2021-02-17 10:18:24 -08:00
parent 9e0ca72827
commit 558a753d3d
4 changed files with 32 additions and 12 deletions

View File

@ -158,6 +158,29 @@ inline NetInfo *get_net_or_empty(CellInfo *cell, const IdString port)
return nullptr; return nullptr;
} }
// Get only value from a forward iterator begin/end pair.
//
// Generates assertion failure if std::distance(begin, end) != 1.
template <typename ForwardIterator>
inline const typename ForwardIterator::reference get_only_value(ForwardIterator begin, ForwardIterator end)
{
NPNR_ASSERT(begin != end);
const typename ForwardIterator::reference ret = *begin;
++begin;
NPNR_ASSERT(begin == end);
return ret;
}
// Get only value from a forward iterator range pair.
//
// Generates assertion failure if std::distance(r.begin(), r.end()) != 1.
template <typename ForwardRange> inline auto get_only_value(ForwardRange r)
{
auto b = r.begin();
auto e = r.end();
return get_only_value(b, e);
}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END
#endif #endif

View File

@ -806,11 +806,8 @@ void Arch::map_cell_pins(CellInfo *cell, int32_t mapping) const
void Arch::map_port_pins(BelId bel, CellInfo *cell) const void Arch::map_port_pins(BelId bel, CellInfo *cell) const
{ {
IdStringRange pins = getBelPins(bel); IdStringRange pins = getBelPins(bel);
NPNR_ASSERT(pins.begin() != pins.end()); IdString pin = get_only_value(pins);
auto b = pins.begin();
IdString pin = *b;
++b;
NPNR_ASSERT(b == pins.end());
NPNR_ASSERT(cell->ports.size() == 1); NPNR_ASSERT(cell->ports.size() == 1);
cell->cell_bel_pins[cell->ports.begin()->first].clear(); cell->cell_bel_pins[cell->ports.begin()->first].clear();
cell->cell_bel_pins[cell->ports.begin()->first].push_back(pin); cell->cell_bel_pins[cell->ports.begin()->first].push_back(pin);

View File

@ -656,7 +656,11 @@ struct BelPinRange
BelPinIterator end() const { return e; } BelPinIterator end() const { return e; }
}; };
struct IdStringIterator struct IdStringIterator : std::iterator<std::forward_iterator_tag,
/*T=*/IdString,
/*Distance=*/ptrdiff_t,
/*pointer=*/IdString *,
/*reference=*/IdString>
{ {
const int32_t *cursor; const int32_t *cursor;

View File

@ -20,6 +20,7 @@
#include "log.h" #include "log.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
@ -235,12 +236,7 @@ void Arch::pack_ports()
placed_cells.emplace(port_cell); placed_cells.emplace(port_cell);
IdStringRange package_bel_pins = getBelPins(package_bel); IdStringRange package_bel_pins = getBelPins(package_bel);
// NPNR_ASSERT(std::distance(package_bel_pins.begin(), package_bel_pins.end()) == 1); IdString pad_pin = get_only_value(package_bel_pins);
IdStringIterator b = package_bel_pins.begin();
NPNR_ASSERT(b != package_bel_pins.end());
++b;
NPNR_ASSERT(b == package_bel_pins.end());
IdString pad_pin = *package_bel_pins.begin();
WireId pad_wire = getBelPinWire(package_bel, pad_pin); WireId pad_wire = getBelPinWire(package_bel, pad_pin);
place_iobufs(pad_wire, ports[port_pair.first].net, tightly_attached_bels, &placed_cells); place_iobufs(pad_wire, ports[port_pair.first].net, tightly_attached_bels, &placed_cells);