Skip to content

Commit

Permalink
🎨 Made bdl_input_iterator into a random access iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelwa committed Jul 25, 2023
1 parent 365c9e7 commit cc28547
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 6 deletions.
66 changes: 60 additions & 6 deletions include/fiction/algorithms/iter/bdl_input_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ namespace fiction
* set. To this end, the iterator alters the given layout. The state enumeration wraps around, i.e. after the last
* possible input state, the first input state is set again.
*
* The iterator is bidirectional and can be used in iterator-based `for` loops.
* The iterator satisfies the requirements of `LegacyRandomAccessIterator` and can be used in iterator-based `for`
* loops.
*
* @tparam Lyt SiDB cell-level layout type.
*/
Expand All @@ -49,6 +50,15 @@ class bdl_input_iterator

set_all_inputs();
}
/**
* Dereference operator. Returns a reference to the layout with the current input state.
*
* @return Reference to the current layout.
*/
[[nodiscard]] Lyt& operator*() const noexcept
{
return layout;
}
/**
* Prefix increment operator. Sets the next input state.
*
Expand All @@ -75,6 +85,20 @@ class bdl_input_iterator

return result;
}
/**
* Addition assignment operator. Sets a next input state.
*
* @param m The amount of input states to skip.
* @return Reference to `this`.
*/
bdl_input_iterator& operator+=(const uint64_t m) noexcept
{
current_input_index += m;

set_all_inputs();

return *this;
}
/**
* Prefix decrement operator. Sets the previous input state.
*
Expand Down Expand Up @@ -102,13 +126,42 @@ class bdl_input_iterator
return result;
}
/**
* Dereference operator. Returns a reference to the layout with the current input state.
* Subtraction assignment operator. Sets a previous input state.
*
* @return Reference to the current layout.
* @param m The amount of input states to skip.
* @return Reference to `this`.
*/
[[nodiscard]] Lyt& operator*() const noexcept
bdl_input_iterator& operator-=(const uint64_t m) noexcept
{
return layout;
current_input_index -= m;

set_all_inputs();

return *this;
}
/**
* Subscript operator. Sets the input state to the current one plus the given subscript.
*
* @param m The amount of input states to skip.
* @return Reference to `this`.
*/
bdl_input_iterator& operator[](const uint64_t m) noexcept
{
current_input_index += m;

set_all_inputs();

return *this;
}
/**
* Subtraction operator. Computes the difference between the current input index and the given iterator ones.
*
* @param other Iterator to compute the difference with.
* @return The difference between the current input index and the given iterator ones.
*/
[[nodiscard]] std::size_t operator-(const bdl_input_iterator& other) const noexcept
{
return current_input_index - other.current_input_index;
}
/**
* Equality operator. Compares the current input index with the given integer.
Expand Down Expand Up @@ -225,7 +278,8 @@ namespace std
template <typename Lyt>
struct iterator_traits<fiction::bdl_input_iterator<Lyt>>
{
using iterator_category = std::bidirectional_iterator_tag;
using iterator_category = std::random_access_iterator_tag;
using difference_type = std::size_t;
using value_type = Lyt;
};
} // namespace std
Expand Down
11 changes: 11 additions & 0 deletions test/algorithms/iter/aspect_ratio_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@
#include <fiction/algorithms/iter/aspect_ratio_iterator.hpp>
#include <fiction/layouts/coordinates.hpp>

#include <iterator>
#include <type_traits>

using namespace fiction;

TEST_CASE("Traits", "[bdl-input-iterator]")
{
CHECK(std::is_same_v<std::iterator_traits<aspect_ratio_iterator<offset::ucoord_t>>::iterator_category,
std::forward_iterator_tag>);

CHECK(std::is_same_v<std::iterator_traits<aspect_ratio_iterator<offset::ucoord_t>>::value_type, offset::ucoord_t>);
}

TEST_CASE("Aspect ratio iteration", "[aspect-ratio-iterator]")
{
aspect_ratio_iterator<offset::ucoord_t> ari{1};
Expand Down
129 changes: 129 additions & 0 deletions test/algorithms/iter/bdl_input_iterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,100 @@
#include <fiction/technology/cell_technologies.hpp>
#include <fiction/types.hpp>

#include <cstdint>
#include <iterator>
#include <type_traits>

using namespace fiction;

TEST_CASE("Traits", "[bdl-input-iterator]")
{
using layout = sidb_cell_clk_lyt_siqad;

CHECK(std::is_same_v<std::iterator_traits<bdl_input_iterator<layout>>::iterator_category,
std::random_access_iterator_tag>);

CHECK(std::is_same_v<std::iterator_traits<bdl_input_iterator<layout>>::value_type, layout>);

CHECK(std::is_same_v<std::iterator_traits<bdl_input_iterator<layout>>::difference_type, std::size_t>);
}

TEST_CASE("Operators", "[bdl-input-iterators]")
{
using layout = sidb_cell_clk_lyt_siqad;

layout lyt{};

bdl_input_iterator<layout> bii{lyt};

CHECK(bii == 0ull);
CHECK(bii != 1ull);

CHECK(bii < 1ull);
CHECK(bii <= 1ull);

CHECK(bii >= 0ull);

// increment
++bii;

CHECK(bii == 1ull);
CHECK(bii != 0ull);

CHECK(bii < 2ull);
CHECK(bii <= 2ull);

CHECK(bii > 0ull);
CHECK(bii >= 0ull);

// decrement
--bii;

CHECK(bii == 0ull);
CHECK(bii != 1ull);

CHECK(bii < 1ull);
CHECK(bii <= 1ull);

CHECK(bii >= 0ull);

// increment assignment
bii += 2ull;

CHECK(bii == 2ull);
CHECK(bii != 1ull);

CHECK(bii < 3ull);
CHECK(bii <= 3ull);

CHECK(bii > 1ull);
CHECK(bii >= 1ull);

const auto bii_cp = bii;

// decrement assignment
bii -= 2ull;

CHECK(bii == 0ull);
CHECK(bii != 1ull);

CHECK(bii < 1ull);
CHECK(bii <= 1ull);

CHECK(bii >= 0ull);

// difference
CHECK(bii_cp - bii == 2ull);

// subscript
CHECK(bii[0] == 0ull);
CHECK(bii[1] == 1ull);
CHECK(bii[2] == 3ull);
CHECK(bii[3] == 6ull);
CHECK(bii[4] == 10ull);

}

TEST_CASE("Empty layout iteration", "[bdl-input-iterator]")
{
using layout = sidb_cell_clk_lyt_siqad;
Expand All @@ -20,6 +112,8 @@ TEST_CASE("Empty layout iteration", "[bdl-input-iterator]")

CHECK((*bii).num_cells() == 0);

// increment

++bii;

CHECK((*bii).num_cells() == 0);
Expand All @@ -28,6 +122,18 @@ TEST_CASE("Empty layout iteration", "[bdl-input-iterator]")

CHECK((*bii).num_cells() == 0);
CHECK((*bii_cp).num_cells() == 0);

// decrement

--bii;

CHECK((*bii).num_cells() == 0);

auto bii_cm = bii--;

CHECK((*bii).num_cells() == 0);

CHECK((*bii_cm).num_cells() == 0);
}

TEST_CASE("BDL wire iteration", "[bdl-input-iterator]")
Expand All @@ -49,6 +155,9 @@ TEST_CASE("BDL wire iteration", "[bdl-input-iterator]")
lyt.assign_cell_type({20, 0, 0}, sidb_technology::cell_type::OUTPUT);

bdl_input_iterator<layout> bii{lyt};
CHECK(bii == 0ull);

// start by incrementing over all input states

// layout at input state 0
const auto& lyt_0 = *bii;
Expand All @@ -58,6 +167,7 @@ TEST_CASE("BDL wire iteration", "[bdl-input-iterator]")
CHECK(lyt_0.get_cell_type({2, 0, 0}) == sidb_technology::cell_type::EMPTY);

++bii;
CHECK(bii == 1ull);

// layout at input state 1
const auto& lyt_1 = *bii;
Expand All @@ -68,11 +178,30 @@ TEST_CASE("BDL wire iteration", "[bdl-input-iterator]")

// doing another iteration should overflow and set it back to 0
++bii;
CHECK(bii == 2ull);

const auto& lyt_2 = *bii;

CHECK(lyt_2.get_cell_type({0, 0, 0}) == sidb_technology::cell_type::INPUT);
CHECK(lyt_2.get_cell_type({2, 0, 0}) == sidb_technology::cell_type::EMPTY);

// finally, decrement back to the initial state, doing another wrap-around

--bii;
CHECK(bii == 1ull);

const auto& lyt_1_1 = *bii;

CHECK(lyt_1_1.get_cell_type({0, 0, 0}) == sidb_technology::cell_type::EMPTY);
CHECK(lyt_1_1.get_cell_type({2, 0, 0}) == sidb_technology::cell_type::INPUT);

--bii;
CHECK(bii == 0ull);

const auto& lyt_0_1 = *bii;

CHECK(lyt_0_1.get_cell_type({0, 0, 0}) == sidb_technology::cell_type::INPUT);
CHECK(lyt_0_1.get_cell_type({2, 0, 0}) == sidb_technology::cell_type::EMPTY);
}

TEST_CASE("SiQAD's AND gate iteration", "[bdl-input-iterator]")
Expand Down

0 comments on commit cc28547

Please sign in to comment.