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 =
typename Alloc::
template rebind< std::pair< T1, T2* > >::other;
106 using allocator21_type =
typename Alloc::
template rebind< std::pair< T2, T1* > >::other;
117 BijectionImplementation(Size size,
bool resize_policy);
123 BijectionImplementation(std::initializer_list< std::pair< T1, T2 > > list);
129 BijectionImplementation(
const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy);
135 template <
typename OtherAlloc >
136 BijectionImplementation(
const BijectionImplementation< T1, T2, OtherAlloc, Gen >& toCopy);
142 BijectionImplementation(BijectionImplementation< T1, T2, Alloc, Gen >&& from)
noexcept;
153 ~BijectionImplementation();
163 BijectionImplementation< T1, T2, Alloc, Gen >&
164 operator=(
const BijectionImplementation< T1, T2, Alloc, Gen >& toCopy);
171 template <
typename OtherAlloc >
172 BijectionImplementation< T1, T2, Alloc, Gen >&
173 operator=(
const BijectionImplementation< T1, T2, OtherAlloc, Gen >& toCopy);
180 BijectionImplementation< T1, T2, Alloc, Gen >&
181 operator=(BijectionImplementation< T1, T2, Alloc, Gen >&& toCopy);
210 iterator begin()
const;
233 const_iterator cbegin()
const;
255 const iterator& end()
const noexcept;
277 const const_iterator& cend()
const noexcept;
300 iterator_safe beginSafe()
const;
324 const_iterator_safe cbeginSafe()
const;
347 const iterator_safe& endSafe()
const noexcept;
371 const const_iterator_safe& cendSafe()
const noexcept;
408 static const iterator_safe& endSafe4Statics();
445 static const iterator& end4Statics();
459 const T1& first(
const T2& second)
const;
470 const T1& firstWithDefault(
const T2& second,
const T1& default_val)
const;
478 const T2& second(
const T1& first)
const;
489 const T2& secondWithDefault(
const T1& second,
const T2& default_val)
const;
498 bool existsFirst(
const T1& first)
const;
507 bool existsSecond(
const T2& second)
const;
518 void insert(
const T1& first,
const T2& second);
529 void insert(T1&& first, T2&& second);
541 template <
typename... Args >
542 void emplace(Args&&... args);
555 bool empty()
const noexcept;
563 Size size()
const noexcept;
573 void eraseFirst(
const T1& first);
583 void eraseSecond(
const T2& second);
589 std::string toString()
const;
601 Size capacity()
const noexcept;
610 void resize(Size new_size);
619 void setResizePolicy(
const bool new_policy)
noexcept;
628 bool resizePolicy()
const noexcept;
635 using HashTable12 = HashTable< T1, T2*, allocator12_type >;
636 using HashTable21 = HashTable< T2, T1*, allocator21_type >;
641 friend class BijectionIteratorSafe< T1, T2 >;
642 friend class BijectionIterator< T1, T2 >;
643 friend class Bijection< T1, T2, Alloc >;
644 template <
typename TT1,
typename TT2,
typename A,
bool >
645 friend class BijectionImplementation;
654 HashTable12 _firstToSecond_;
657 HashTable21 _secondToFirst_;
668 template <
typename OtherAlloc >
669 void _copy_(
const HashTable< T1, T2*, OtherAlloc >& source);
677 typename HashTable12::value_type* _insert_(
const T1& first,
const T2& second);
685 typename HashTable12::value_type* _insert_(T1&& first, T2&& second);
688 #ifndef DOXYGEN_SHOULD_SKIP_THIS 717 template <
typename T1,
typename T2,
typename Alloc >
718 class BijectionImplementation< T1, T2, Alloc,
true > {
722 using type1_type = T1;
723 using type1_reference = T1&;
724 using type1_const_reference =
const T1&;
725 using type1_pointer = T1*;
726 using type1_const_pointer =
const T1*;
727 using type2_type = T2;
728 using type2_reference = T2&;
729 using type2_const_reference =
const T2&;
730 using type2_pointer = T2*;
731 using type2_const_pointer =
const T2*;
732 using size_type = std::size_t;
733 using difference_type = std::ptrdiff_t;
734 using allocator_type = Alloc;
735 using iterator = BijectionIterator< T1, T2 >;
736 using const_iterator = BijectionIterator< T1, T2 >;
737 using iterator_safe = BijectionIteratorSafe< T1, T2 >;
738 using const_iterator_safe = BijectionIteratorSafe< T1, T2 >;
740 using allocator12_type =
typename Alloc::
template rebind< std::pair< T1, T2 > >::other;
741 using allocator21_type =
typename Alloc::
template rebind< std::pair< T2, T1 > >::other;
752 BijectionImplementation(Size size,
bool resize_policy);
758 BijectionImplementation(std::initializer_list< std::pair< T1, T2 > > list);
764 BijectionImplementation(
const BijectionImplementation< T1, T2, Alloc,
true >& toCopy);
770 template <
typename OtherAlloc >
771 BijectionImplementation(
const BijectionImplementation< T1, T2, OtherAlloc,
true >& toCopy);
777 BijectionImplementation(BijectionImplementation< T1, T2, Alloc,
true >&& from)
noexcept;
788 ~BijectionImplementation();
798 BijectionImplementation< T1, T2, Alloc,
true >&
799 operator=(
const BijectionImplementation< T1, T2, Alloc,
true >& toCopy);
806 template <
typename OtherAlloc >
807 BijectionImplementation< T1, T2, Alloc,
true >&
808 operator=(
const BijectionImplementation< T1, T2, OtherAlloc,
true >& toCopy);
815 BijectionImplementation< T1, T2, Alloc,
true >&
816 operator=(BijectionImplementation< T1, T2, Alloc,
true >&& from);
845 iterator begin()
const;
868 const_iterator cbegin()
const;
890 const iterator& end()
const noexcept;
912 const const_iterator& cend()
const noexcept;
935 iterator_safe beginSafe()
const;
959 const_iterator_safe cbeginSafe()
const;
982 const iterator_safe& endSafe()
const noexcept;
1006 const const_iterator_safe& cendSafe()
const noexcept;
1043 static const iterator_safe& endSafe4Statics();
1080 static const iterator& end4Statics();
1094 const T1& first(T2 second)
const;
1105 const T1& firstWithDefault(T2 second, T1 default_val)
const;
1113 const T2& second(T1 first)
const;
1124 const T2& secondWithDefault(T1 first, T2 default_val)
const;
1133 bool existsFirst(T1 first)
const;
1142 bool existsSecond(T2 second)
const;
1153 void insert(T1 first, T2 second);
1165 template <
typename... Args >
1166 void emplace(Args&&... args);
1179 bool empty()
const noexcept;
1187 Size size()
const noexcept;
1197 void eraseFirst(T1 first);
1207 void eraseSecond(T2 second);
1213 std::string toString()
const;
1225 Size capacity()
const noexcept;
1234 void resize(Size new_size);
1243 void setResizePolicy(
const bool new_policy)
noexcept;
1252 bool resizePolicy()
const noexcept;
1259 using HashTable12 = HashTable< T1, T2, allocator12_type >;
1260 using HashTable21 = HashTable< T2, T1, allocator21_type >;
1265 friend class BijectionIteratorSafe< T1, T2 >;
1266 friend class BijectionIterator< T1, T2 >;
1267 friend class Bijection< T1, T2, Alloc >;
1268 template <
typename TT1,
typename TT2,
typename A,
bool >
1269 friend class BijectionImplementation;
1278 HashTable12 _firstToSecond_;
1281 HashTable21 _secondToFirst_;
1292 template <
typename OtherAlloc >
1293 void _copy_(
const HashTable< T1, T2, OtherAlloc >& f2s);
1301 void _insert_(
const T1 first,
const T2 second);
1316 class BijectionIteratorStaticEnd {
1318 template <
typename T1,
typename T2,
typename Alloc,
bool >
1319 friend class BijectionImplementation;
1323 static const BijectionIteratorSafe<
int,
int >* _BijectionIterEndSafe_;
1326 static const BijectionIterator<
int,
int >* _BijectionIterEnd_;
1333 static const BijectionIteratorSafe<
int,
int >* endSafe4Statics();
1339 static const BijectionIterator<
int,
int >* end4Statics();
1351 template <
bool gen >
1352 struct BijectionIteratorGet {
1358 template <
typename T >
1359 INLINE
static const T& op_second(
const T* x) {
1374 struct BijectionIteratorGet<
true > {
1380 template <
typename T >
1381 INLINE
static const T& op_second(
const T& x) {
1399 template <
typename T1,
typename T2 >
1400 class BijectionIteratorSafe {
1401 template <
typename TT1,
typename TT2,
typename Alloc,
bool >
1402 friend class BijectionImplementation;
1407 using iterator_category = std::forward_iterator_tag;
1408 using type1_type = T1;
1409 using type1_reference = T1&;
1410 using type1_const_reference =
const T1&;
1411 using type1_pointer = T1*;
1412 using type1_const_pointer =
const T1*;
1413 using type2_type = T2;
1414 using type2_reference = T2&;
1415 using type2_const_reference =
const T2&;
1416 using type2_pointer = T2*;
1417 using type2_const_pointer =
const T2*;
1418 using difference_type = std::ptrdiff_t;
1427 = BijectionIteratorGet< std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >;
1435 template <
typename Alloc,
bool Gen >
1436 BijectionIteratorSafe(
const BijectionImplementation< T1, T2, Alloc, Gen >& bijection);
1447 BijectionIteratorSafe()
noexcept;
1453 template <
typename Alloc >
1454 BijectionIteratorSafe(
const Bijection< T1, T2, Alloc >& bijection);
1460 BijectionIteratorSafe(
const BijectionIteratorSafe< T1, T2 >& from);
1466 BijectionIteratorSafe(BijectionIteratorSafe< T1, T2 >&& from)
noexcept;
1471 ~BijectionIteratorSafe()
noexcept;
1484 BijectionIteratorSafe< T1, T2 >& operator=(
const BijectionIteratorSafe< T1, T2 >& toCopy);
1491 BijectionIteratorSafe< T1, T2 >& operator=(BijectionIteratorSafe< T1, T2 >&& toMove)
noexcept;
1499 BijectionIteratorSafe< T1, T2 >& operator++()
noexcept;
1512 BijectionIteratorSafe< T1, T2 >& operator+=(Size nb)
noexcept;
1525 BijectionIteratorSafe< T1, T2 > operator+(Size nb)
noexcept;
1532 bool operator!=(
const BijectionIteratorSafe< T1, T2 >& toCompare)
const noexcept;
1539 bool operator==(
const BijectionIteratorSafe< T1, T2 >& toCompare)
const noexcept;
1553 const T1& first()
const;
1561 const T2& second()
const;
1567 using HashTable12 =
typename std::conditional<
1568 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value,
1569 HashTable< T1, T2, std::allocator< std::pair< T1, T2 > > >,
1570 HashTable< T1, T2*, std::allocator< std::pair< T1, T2* > > > >::type;
1574 using HashIter =
typename HashTable12::const_iterator_safe;
1592 template <
typename T1,
typename T2 >
1593 class BijectionIterator {
1594 template <
typename TT1,
typename TT2,
typename Alloc,
bool >
1595 friend class BijectionImplementation;
1600 using iterator_category = std::forward_iterator_tag;
1601 using type1_type = T1;
1602 using type1_reference = T1&;
1603 using type1_const_reference =
const T1&;
1604 using type1_pointer = T1*;
1605 using type1_const_pointer =
const T1*;
1606 using type2_type = T2;
1607 using type2_reference = T2&;
1608 using type2_const_reference =
const T2&;
1609 using type2_pointer = T2*;
1610 using type2_const_pointer =
const T2*;
1611 using difference_type = std::ptrdiff_t;
1620 = BijectionIteratorGet< std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >;
1626 template <
typename Alloc,
bool Gen >
1627 BijectionIterator(
const BijectionImplementation< T1, T2, Alloc, Gen >& bijection);
1638 BijectionIterator()
noexcept;
1644 template <
typename Alloc >
1645 BijectionIterator(
const Bijection< T1, T2, Alloc >& bijection);
1651 BijectionIterator(
const BijectionIterator< T1, T2 >& from);
1657 BijectionIterator(BijectionIterator< T1, T2 >&& from)
noexcept;
1662 ~BijectionIterator()
noexcept;
1675 BijectionIterator< T1, T2 >& operator=(
const BijectionIterator< T1, T2 >& toCopy);
1682 BijectionIterator< T1, T2 >& operator=(BijectionIterator< T1, T2 >&& toMove)
noexcept;
1691 BijectionIterator< T1, T2 >& operator++()
noexcept;
1704 BijectionIterator< T1, T2 >& operator+=(Size nb)
noexcept;
1714 BijectionIterator< T1, T2 > operator+(Size nb)
noexcept;
1721 bool operator!=(
const BijectionIterator< T1, T2 >& toCompare)
const noexcept;
1728 bool operator==(
const BijectionIterator< T1, T2 >& toCompare)
const noexcept;
1742 const T1& first()
const;
1750 const T2& second()
const;
1756 using HashTable12 =
typename std::conditional<
1757 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value,
1758 HashTable< T1, T2, std::allocator< std::pair< T1, T2 > > >,
1759 HashTable< T1, T2*, std::allocator< std::pair< T1, T2* > > > >::type;
1760 using HashIter =
typename HashTable12::const_iterator;
1785 template <
typename T1,
typename T2,
typename Alloc = std::allocator< T2 > >
1787 public BijectionImplementation< T1,
1790 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value > {
1794 using type1_type = T1;
1795 using type1_reference = T1&;
1796 using type1_const_reference =
const T1&;
1797 using type1_pointer = T1*;
1798 using type1_const_pointer =
const T1*;
1799 using type2_type = T2;
1800 using type2_reference = T2&;
1801 using type2_const_reference =
const T2&;
1802 using type2_pointer = T2*;
1803 using type2_const_pointer =
const T2*;
1804 using size_type = std::size_t;
1805 using difference_type = std::ptrdiff_t;
1806 using allocator_type = Alloc;
1807 using iterator = BijectionIterator< T1, T2 >;
1808 using const_iterator = BijectionIterator< T1, T2 >;
1809 using iterator_safe = BijectionIteratorSafe< T1, T2 >;
1810 using const_iterator_safe = BijectionIteratorSafe< T1, T2 >;
1812 using allocator1_type =
typename Alloc::
template rebind< T1* >::other;
1813 using allocator2_type =
typename Alloc::
template rebind< T2* >::other;
1817 using Implementation
1818 = BijectionImplementation< T1,
1821 std::is_scalar< T1 >::value && std::is_scalar< T2 >::value >;
1835 Bijection(Size size = HashTableConst::default_size,
1836 bool resize_policy = HashTableConst::default_resize_policy);
1842 Bijection(std::initializer_list< std::pair< T1, T2 > > list);
1848 Bijection(
const Bijection< T1, T2, Alloc >& toCopy);
1855 template <
typename OtherAlloc >
1856 Bijection(
const Bijection< T1, T2, OtherAlloc >& toCopy);
1862 Bijection(Bijection< T1, T2, Alloc >&& from)
noexcept;
1880 Bijection< T1, T2, Alloc >& operator=(
const Bijection< T1, T2, Alloc >& toCopy);
1887 template <
typename OtherAlloc >
1888 Bijection< T1, T2, Alloc >& operator=(
const Bijection< T1, T2, OtherAlloc >& toCopy);
1894 Bijection< T1, T2, Alloc >& operator=(Bijection< T1, T2, Alloc >&& bij);
1908 template <
typename T1,
typename T2,
typename Alloc >
1909 std::ostream& operator<<(std::ostream&,
const Bijection< T1, T2, Alloc >& bijection);
1914 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1915 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1916 extern template class gum::Bijection<
int,
int >;
1919 #ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1920 # ifndef GUM_NO_EXTERN_TEMPLATE_CLASS 1921 extern template class gum::Bijection< std::string, std::string >;
1927 #include <agrum/tools/core/bijection_tpl.h>