32 #ifndef GUM_BIJECTION_H 33 #define GUM_BIJECTION_H 35 #include <initializer_list> 39 #include <type_traits> 41 #include <agrum/tools/core/hashTable.h> 45 #ifndef DOXYGEN_SHOULD_SKIP_THIS 47 template <
typename T1,
typename T2 >
48 class BijectionIteratorSafe;
49 template <
typename T1,
typename T2 >
50 class BijectionIterator;
51 template <
typename T1,
typename T2,
typename Alloc,
bool >
52 class BijectionImplementation;
53 template <
typename T1,
typename T2,
typename Alloc >
83 template <
typename T1,
typename T2,
typename Alloc,
bool Gen >
84 class BijectionImplementation {
88 using type1_type = T1;
89 using type1_reference = T1&;
90 using type1_const_reference =
const T1&;
91 using type1_pointer = T1*;
92 using type1_const_pointer =
const T1*;
93 using type2_type = T2;
94 using type2_reference = T2&;
95 using type2_const_reference =
const T2&;
96 using type2_pointer = T2*;
97 using type2_const_pointer =
const T2*;
98 using size_type = std::size_t;
99 using difference_type = std::ptrdiff_t;
100 using allocator_type = Alloc;
101 using iterator = BijectionIterator< T1, T2 >;
102 using const_iterator = BijectionIterator< T1, T2 >;
103 using iterator_safe = BijectionIteratorSafe< T1, T2 >;
104 using const_iterator_safe = BijectionIteratorSafe< T1, T2 >;
105 using allocator12_type =
106 typename Alloc::
template rebind< std::pair< T1, T2* > >::other;
107 using allocator21_type =
108 typename Alloc::
template rebind< std::pair< T2, T1* > >::other;
119 BijectionImplementation(Size size,
bool resize_policy);
125 BijectionImplementation(std::initializer_list< std::pair< T1, T2 > > list);
131 BijectionImplementation(
132 const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy);
138 template <
typename OtherAlloc >
139 BijectionImplementation(
140 const BijectionImplementation< T1, T2, OtherAlloc, Gen >& toCopy);
146 BijectionImplementation(
147 BijectionImplementation< T1, T2, Alloc, Gen >&& from)
noexcept;
158 ~BijectionImplementation();
168 BijectionImplementation< T1, T2, Alloc, Gen >&
169 operator=(
const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy);
176 template <
typename OtherAlloc >
177 BijectionImplementation< T1, T2, Alloc, Gen >&
178 operator=(
const BijectionImplementation< T1, T2, OtherAlloc, Gen >& toCopy);
185 BijectionImplementation< T1, T2, Alloc, Gen >&
186 operator=(BijectionImplementation< T1, T2, Alloc, Gen >&& toCopy);
215 iterator begin()
const;
238 const_iterator cbegin()
const;
260 const iterator& end()
const noexcept;
282 const const_iterator& cend()
const noexcept;
305 iterator_safe beginSafe()
const;
329 const_iterator_safe cbeginSafe()
const;
352 const iterator_safe& endSafe()
const noexcept;
376 const const_iterator_safe& cendSafe()
const noexcept;
413 static const iterator_safe& endSafe4Statics();
450 static const iterator& end4Statics();
464 const T1& first(
const T2& second)
const;
475 const T1& firstWithDefault(
const T2& second,
const T1& default_val)
const;
483 const T2& second(
const T1& first)
const;
494 const T2& secondWithDefault(
const T1& second,
const T2& default_val)
const;
503 bool existsFirst(
const T1& first)
const;
512 bool existsSecond(
const T2& second)
const;
523 void insert(
const T1& first,
const T2& second);
534 void insert(T1&& first, T2&& second);
546 template <
typename... Args >
547 void emplace(Args&&... args);
560 bool empty()
const noexcept;
568 Size size()
const noexcept;
578 void eraseFirst(
const T1& first);
588 void eraseSecond(
const T2& second);
594 std::string toString()
const;
606 Size capacity()
const noexcept;
615 void resize(Size new_size);
624 void setResizePolicy(
const bool new_policy)
noexcept;
633 bool resizePolicy()
const noexcept;
640 using HashTable12 = HashTable< T1, T2*, allocator12_type >;
641 using HashTable21 = HashTable< T2, T1*, allocator21_type >;
646 friend class BijectionIteratorSafe< T1, T2 >;
647 friend class BijectionIterator< T1, T2 >;
648 friend class Bijection< T1, T2, Alloc >;
649 template <
typename TT1,
typename TT2,
typename A,
bool >
650 friend class BijectionImplementation;
659 HashTable12 firstToSecond__;
662 HashTable21 secondToFirst__;
673 template <
typename OtherAlloc >
674 void copy__(
const HashTable< T1, T2*, OtherAlloc >& source);
682 typename HashTable12::value_type* insert__(
const T1& first,
const T2& second);
690 typename HashTable12::value_type* insert__(T1&& first, T2&& second);
693 #ifndef DOXYGEN_SHOULD_SKIP_THIS 722 template <
typename T1,
typename T2,
typename Alloc >
723 class BijectionImplementation< T1, T2, Alloc,
true > {
727 using type1_type = T1;
728 using type1_reference = T1&;
729 using type1_const_reference =
const T1&;
730 using type1_pointer = T1*;
731 using type1_const_pointer =
const T1*;
732 using type2_type = T2;
733 using type2_reference = T2&;
734 using type2_const_reference =
const T2&;
735 using type2_pointer = T2*;
736 using type2_const_pointer =
const T2*;
737 using size_type = std::size_t;
738 using difference_type = std::ptrdiff_t;
739 using allocator_type = Alloc;
740 using iterator = BijectionIterator< T1, T2 >;
741 using const_iterator = BijectionIterator< T1, T2 >;
742 using iterator_safe = BijectionIteratorSafe< T1, T2 >;
743 using const_iterator_safe = BijectionIteratorSafe< T1, T2 >;
745 using allocator12_type =
746 typename Alloc::
template rebind< std::pair< T1, T2 > >::other;
747 using allocator21_type =
748 typename Alloc::
template rebind< std::pair< T2, T1 > >::other;
759 BijectionImplementation(Size size,
bool resize_policy);
765 BijectionImplementation(std::initializer_list< std::pair< T1, T2 > > list);
771 BijectionImplementation(
772 const BijectionImplementation< T1, T2, Alloc,
true >& toCopy);
778 template <
typename OtherAlloc >
779 BijectionImplementation(
780 const BijectionImplementation< T1, T2, OtherAlloc,
true >& toCopy);
786 BijectionImplementation(
787 BijectionImplementation< T1, T2, Alloc,
true >&& from)
noexcept;
798 ~BijectionImplementation();
808 BijectionImplementation< T1, T2, Alloc,
true >&
809 operator=(
const BijectionImplementation< T1, T2, Alloc,
true >& toCopy);
816 template <
typename OtherAlloc >
817 BijectionImplementation< T1, T2, Alloc,
true >& operator=(
818 const BijectionImplementation< T1, T2, OtherAlloc,
true >& toCopy);
825 BijectionImplementation< T1, T2, Alloc,
true >&
826 operator=(BijectionImplementation< T1, T2, Alloc,
true >&& from);
855 iterator begin()
const;
878 const_iterator cbegin()
const;
900 const iterator& end()
const noexcept;
922 const const_iterator& cend()
const noexcept;
945 iterator_safe beginSafe()
const;
969 const_iterator_safe cbeginSafe()
const;
992 const iterator_safe& endSafe()
const noexcept;
1016 const const_iterator_safe& cendSafe()
const noexcept;
1053 static const iterator_safe& endSafe4Statics();
1090 static const iterator& end4Statics();
1104 const T1& first(T2 second)
const;
1115 const T1& firstWithDefault(T2 second, T1 default_val)
const;
1123 const T2& second(T1 first)
const;
1134 const T2& secondWithDefault(T1 first, T2 default_val)
const;
1143 bool existsFirst(T1 first)
const;
1152 bool existsSecond(T2 second)
const;
1163 void insert(T1 first, T2 second);
1175 template <
typename... Args >
1176 void emplace(Args&&... args);
1189 bool empty()
const noexcept;
1197 Size size()
const noexcept;
1207 void eraseFirst(T1 first);
1217 void eraseSecond(T2 second);
1223 std::string toString()
const;
1235 Size capacity()
const noexcept;
1244 void resize(Size new_size);
1253 void setResizePolicy(
const bool new_policy)
noexcept;
1262 bool resizePolicy()
const noexcept;
1269 using HashTable12 = HashTable< T1, T2, allocator12_type >;
1270 using HashTable21 = HashTable< T2, T1, allocator21_type >;
1275 friend class BijectionIteratorSafe< T1, T2 >;
1276 friend class BijectionIterator< T1, T2 >;
1277 friend class Bijection< T1, T2, Alloc >;
1278 template <
typename TT1,
typename TT2,
typename A,
bool >
1279 friend class BijectionImplementation;
1288 HashTable12 firstToSecond__;
1291 HashTable21 secondToFirst__;
1302 template <
typename OtherAlloc >
1303 void copy__(
const HashTable< T1, T2, OtherAlloc >& f2s);
1311 void insert__(
const T1 first,
const T2 second);
1326 class BijectionIteratorStaticEnd {
1328 template <
typename T1,
typename T2,
typename Alloc,
bool >
1329 friend class BijectionImplementation;
1333 static const BijectionIteratorSafe<
int,
int >* BijectionIterEndSafe__;
1336 static const BijectionIterator<
int,
int >* BijectionIterEnd__;
1343 static const BijectionIteratorSafe<
int,
int >* endSafe4Statics();
1349 static const BijectionIterator<
int,
int >* end4Statics();
1361 template <
bool gen >
1362 struct BijectionIteratorGet {
1368 template <
typename T >
1369 INLINE
static const T& op_second(
const T* x) {
1384 struct BijectionIteratorGet<
true > {
1390 template <
typename T >
1391 INLINE
static const T& op_second(
const T& x) {
1409 template <
typename T1,
typename T2 >
1410 class BijectionIteratorSafe {
1411 template <
typename TT1,
typename TT2,
typename Alloc,
bool >
1412 friend class BijectionImplementation;
1417 using iterator_category = std::forward_iterator_tag;
1418 using type1_type = T1;
1419 using type1_reference = T1&;
1420 using type1_const_reference =
const T1&;
1421 using type1_pointer = T1*;
1422 using type1_const_pointer =
const T1*;
1423 using type2_type = T2;
1424 using type2_reference = T2&;
1425 using type2_const_reference =
const T2&;
1426 using type2_pointer = T2*;
1427 using type2_const_pointer =
const T2*;
1428 using difference_type = std::ptrdiff_t;
1436 using Getter = BijectionIteratorGet< std::is_scalar< T1 >::value
1437 && std::is_scalar< T2 >::value >;
1445 template <
typename Alloc,
bool Gen >
1446 BijectionIteratorSafe(
1447 const BijectionImplementation< T1, T2, Alloc, Gen >& bijection);
1458 BijectionIteratorSafe()
noexcept;
1464 template <
typename Alloc >
1465 BijectionIteratorSafe(
const Bijection< T1, T2, Alloc >& bijection);
1471 BijectionIteratorSafe(
const BijectionIteratorSafe< T1, T2 >& from);
1477 BijectionIteratorSafe(BijectionIteratorSafe< T1, T2 >&& from)
noexcept;
1482 ~BijectionIteratorSafe()
noexcept;
1495 BijectionIteratorSafe< T1, T2 >&
1496 operator=(
const BijectionIteratorSafe< T1, T2 >& toCopy);
1503 BijectionIteratorSafe< T1, T2 >&
1504 operator=(BijectionIteratorSafe< T1, T2 >&& toMove)
noexcept;
1512 BijectionIteratorSafe< T1, T2 >& operator++()
noexcept;
1525 BijectionIteratorSafe< T1, T2 >& operator+=(Size nb)
noexcept;
1538 BijectionIteratorSafe< T1, T2 > operator+(Size nb)
noexcept;
1546 operator!=(
const BijectionIteratorSafe< T1, T2 >& toCompare)
const noexcept;
1554 operator==(
const BijectionIteratorSafe< T1, T2 >& toCompare)
const noexcept;
1568 const T1& first()
const;
1576 const T2& second()
const;
1582 using HashTable12 =
typename std::conditional<
1583 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value,
1584 HashTable< T1, T2, std::allocator< std::pair< T1, T2 > > >,
1585 HashTable< T1, T2*, std::allocator< std::pair< T1, T2* > > > >::type;
1589 using HashIter =
typename HashTable12::const_iterator_safe;
1607 template <
typename T1,
typename T2 >
1608 class BijectionIterator {
1609 template <
typename TT1,
typename TT2,
typename Alloc,
bool >
1610 friend class BijectionImplementation;
1615 using iterator_category = std::forward_iterator_tag;
1616 using type1_type = T1;
1617 using type1_reference = T1&;
1618 using type1_const_reference =
const T1&;
1619 using type1_pointer = T1*;
1620 using type1_const_pointer =
const T1*;
1621 using type2_type = T2;
1622 using type2_reference = T2&;
1623 using type2_const_reference =
const T2&;
1624 using type2_pointer = T2*;
1625 using type2_const_pointer =
const T2*;
1626 using difference_type = std::ptrdiff_t;
1634 using Getter = BijectionIteratorGet< std::is_scalar< T1 >::value
1635 && std::is_scalar< T2 >::value >;
1641 template <
typename Alloc,
bool Gen >
1643 const BijectionImplementation< T1, T2, Alloc, Gen >& bijection);
1654 BijectionIterator()
noexcept;
1660 template <
typename Alloc >
1661 BijectionIterator(
const Bijection< T1, T2, Alloc >& bijection);
1667 BijectionIterator(
const BijectionIterator< T1, T2 >& from);
1673 BijectionIterator(BijectionIterator< T1, T2 >&& from)
noexcept;
1678 ~BijectionIterator()
noexcept;
1691 BijectionIterator< T1, T2 >&
1692 operator=(
const BijectionIterator< T1, T2 >& toCopy);
1699 BijectionIterator< T1, T2 >&
1700 operator=(BijectionIterator< T1, T2 >&& toMove)
noexcept;
1709 BijectionIterator< T1, T2 >& operator++()
noexcept;
1722 BijectionIterator< T1, T2 >& operator+=(Size nb)
noexcept;
1732 BijectionIterator< T1, T2 > operator+(Size nb)
noexcept;
1739 bool operator!=(
const BijectionIterator< T1, T2 >& toCompare)
const noexcept;
1746 bool operator==(
const BijectionIterator< T1, T2 >& toCompare)
const noexcept;
1760 const T1& first()
const;
1768 const T2& second()
const;
1774 using HashTable12 =
typename std::conditional<
1775 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value,
1776 HashTable< T1, T2, std::allocator< std::pair< T1, T2 > > >,
1777 HashTable< T1, T2*, std::allocator< std::pair< T1, T2* > > > >::type;
1778 using HashIter =
typename HashTable12::const_iterator;
1803 template <
typename T1,
typename T2,
typename Alloc = std::allocator< T2 > >
1805 public BijectionImplementation< T1,
1808 std::is_scalar< T1 >::value
1809 && std::is_scalar< T2 >::value > {
1813 using type1_type = T1;
1814 using type1_reference = T1&;
1815 using type1_const_reference =
const T1&;
1816 using type1_pointer = T1*;
1817 using type1_const_pointer =
const T1*;
1818 using type2_type = T2;
1819 using type2_reference = T2&;
1820 using type2_const_reference =
const T2&;
1821 using type2_pointer = T2*;
1822 using type2_const_pointer =
const T2*;
1823 using size_type = std::size_t;
1824 using difference_type = std::ptrdiff_t;
1825 using allocator_type = Alloc;
1826 using iterator = BijectionIterator< T1, T2 >;
1827 using const_iterator = BijectionIterator< T1, T2 >;
1828 using iterator_safe = BijectionIteratorSafe< T1, T2 >;
1829 using const_iterator_safe = BijectionIteratorSafe< T1, T2 >;
1831 using allocator1_type =
typename Alloc::
template rebind< T1* >::other;
1832 using allocator2_type =
typename Alloc::
template rebind< T2* >::other;
1836 using Implementation
1837 = BijectionImplementation< T1,
1840 std::is_scalar< T1 >::value
1841 && std::is_scalar< T2 >::value >;
1855 Bijection(Size size = HashTableConst::default_size,
1856 bool resize_policy = HashTableConst::default_resize_policy);
1862 Bijection(std::initializer_list< std::pair< T1, T2 > > list);
1868 Bijection(
const Bijection< T1, T2, Alloc >& toCopy);
1875 template <
typename OtherAlloc >
1876 Bijection(
const Bijection< T1, T2, OtherAlloc >& toCopy);
1882 Bijection(Bijection< T1, T2, Alloc >&& from)
noexcept;
1900 Bijection< T1, T2, Alloc >&
1901 operator=(
const Bijection< T1, T2, Alloc >& toCopy);
1908 template <
typename OtherAlloc >
1909 Bijection< T1, T2, Alloc >&
1910 operator=(
const Bijection< T1, T2, OtherAlloc >& toCopy);
1916 Bijection< T1, T2, Alloc >& operator=(Bijection< T1, T2, Alloc >&& bij);
1930 template <
typename T1,
typename T2,
typename Alloc >
1931 std::ostream& operator<<(std::ostream&,
1932 const Bijection< T1, T2, Alloc >& bijection);
1937 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1938 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1939 extern template class gum::Bijection<
int,
int >;
1942 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1943 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1944 extern template class gum::Bijection< std::string, std::string >;
1950 #include <agrum/tools/core/bijection_tpl.h>