Placements

template<typename T> class Placements

The placements class has one template parameter, it represents the placement id. Specify a type that will not overflow based on the number of nodes of your networks.

Constructors

Placements() noexcept;

There is only a single default constructor.

Iterators

const_iterator<T> cbegin() const noexcept;
const_iterator<T> cend() const noexcept;

The objects of this class are iterable, as shown in the example snippet below:

using namespace electra::placement;

Placements<int32_t> ps;

for( auto it{ ps.cbegin() }; it!=ps.cend(); ++it )
{
  // Code goes here
}

Public Methods

Element Access

template<typename U = std::pair<T,T>>
std::optional<T> at(U&& u) const noexcept;

Given a region, get a placement id. Electra uses the std::optional C++ feature, so you can easily verify if a placement is found or not and deal with the latter. An example is shown in the snippet below:

if( auto res { placements.at( {8,8} ) } )
{
  std::cout << "Placement found, id: " << *res << std::endl;
}
else
{
  std::cerr << "Placement not found" << std::endl;
}

Capacity

auto size() const noexcept;

Returns the number of placements of an object.

Modifiers

template<typename U = std::pair<std::pair<T,T>,T>>
void insert(U&& u) noexcept;

In a given region, inserts a placement, an example is shown below:

placements.insert( {{ 0,2},1} );
placements.insert( {{-2,4},2} );

template<typename U>
void erase(U&& u) const noexcept;

Erases an element given its id. An usage example is shown below:

if( auto id {placements.at({-10,8})} )
{
  placements.erase(*id);
  std::cout << "Erased element with id: " << *id << std::endl;
}
else
{
  std::cout << "Failed to erase, element not found" << std::endl;
}

Lookup

template<typename U = T>
std::optional<std::pair<T,T>> find(U&& u) const noexcept;

Given a placement id obtain its region, an usage example is shown below:

using namespace electra::placement;

Placements<int32_t> placements;

placements.insert( {{4,8},9} );

if( auto id {placements.find(9)} )
{
  std::cout << "Region: (" << id->first << ","
    << id->second << ")" << std::endl;
}
else
{
  std::cout << "Could not find a region with the given placement id"
    << std::endl;
}

Which outputs:

→ Region: (4,8)


std::pair<T,T> get_area() const noexcept;

Get the area the placement occupy; the first element is the width and the second the height. A usage example is shown below:

using namespace electra::placement;

Placements<int32_t> placements;

placements.insert( {{ 0,2},1} );
placements.insert( {{-2,4},2} );

auto area { placements.get_area() };

std::cout << "Area: " << area.first << " x " << area.second << std::endl;

Which yields:

→ Area: 3 x 3

Wires

template<typename T> class Wires

The wires class has one template parameter, it represents the wire type. The wire coordinates are not relative, so specify a type, that, for your use case, will not overflow.

Constructors

Wires();

There is a single default constructor.

Iterators

const_iterator::const_iterator<_Wires<T>,
  typename _Wires<T>::const_iterator> cbegin() const noexcept;
const_iterator::const_iterator<_Wires<T>,
  typename _Wires<T>::const_iterator> cend() const noexcept;

Objects of this class are iterable, each iteration yields a compact wire, which is expanded uppon dereferencing with the * or -> operators; therefore avoiding overhead during each iteration. An example is shown below:

#include <electra/wires.hpp>

electra::wire::Wires<int32_t> wires;

wires.insert( {{3,1},{3,2},{3,3},{3,4}} );
wires.insert( {{-1,1},{-2,1},{-2,2},{-2,3}} );

for( auto it{ wires.cbegin() }; it != wires.cend(); ++it)
{
  // Code goes here
}

Public Methods

Capacity

auto size() const noexcept;

Returns the current number of wires in the data structure.

Modifiers

template<typename U = std::vector<std::pair<T,T>>>
void insert(U&& u) noexcept;

Inserts a wire to be automatically shrunk by Electra. Example:

// Using an r-value
wires.insert( {{3,1},{3,2},{3,3},{3,4}} );

// Using your defined wire type and lvalues
using Wire = std::vector<std::pair<int32_t,int32_t>>;

Wire w { {3,2},{3,1},{3,0},{4,0},{5,0} };

wires.insert( w );

template<typename U = std::pair<T,T>>
void erase(U&& a, U&& b) noexcept;

Given a universal or forwarding reference, erases a wire using its initial and final pair of coordinates. Example:

// Inserts a new wire
wires.insert({{3,1},{3,2},{3,3},{3,4}});

// Removes using the first and last coordinates
wires.erase({3,1},{3,4});

Lookup

template<typename U = std::pair<T,T>>
std::optional<const_iterator::const_iterator<_Wires<T>,
  typename _Wires<T>::const_iterator>> find(U&& a, U&& b) noexcept;

Returns a iterator if a wire is found between the two coordinates, else returns std::nullopt. For accessing the iterator use the * or -> operators.

auto get_area() const noexcept;

Returns the area occupied by the current wires.

Operations

template<typename U>
void write(U&& filename) const noexcept;

Writes the current wires data structure to the json format using the forwarding reference filename. Example:

wires.write( "wires.json" );

template<typename U>
void read(U&& filename) noexcept;

Reads a previously written wires data structure. Example:

wires.read("wires.json");