Line data Source code
1 : /**
2 : * @file BDictionary.h
3 : * @copyright (c) 2014 by Petr Zemek (s3rvac@gmail.com) and contributors
4 : * @license BSD, see the @c LICENSE file for more details
5 : * @brief Representation of a dictionary.
6 : */
7 :
8 : #ifndef BENCODING_BDICTIONARY_H
9 : #define BENCODING_BDICTIONARY_H
10 :
11 : #include <initializer_list>
12 : #include <map>
13 : #include <memory>
14 :
15 : #include "BItem.h"
16 :
17 : namespace bencoding {
18 :
19 : class BString;
20 :
21 : /**
22 : * @brief Representation of a dictionary.
23 : *
24 : * The interface models the interface of @c std::map.
25 : *
26 : * According to the <a
27 : * href="https://wiki.theory.org/BitTorrentSpecification#Bencoding">specification</a>,
28 : * the keys should appear in a lexicographical order by the string values. This
29 : * has the following consequences for the users of the BDictionary class:
30 : * - When accessing or modifying elements by @c std::shared_ptr<BString>, its
31 : * value is taken into account, not its address. That is, two different smart
32 : * pointers pointing to strings with equal values are considered to be equal
33 : * when accessing or modifying elements.
34 : * - The iterators return elements in a sorted order by the values of string
35 : * keys, despite using smart pointers to index the dictionary.
36 : *
37 : * Use create() to create instances of the class.
38 : */
39 70 : class BDictionary: public BItem {
40 : private:
41 : /**
42 : * @brief Comparator of keys for the dictionary.
43 : *
44 : * It compares the instances of BString inside smart pointers by their value
45 : * rather than by their address.
46 : */
47 : class BStringByValueComparator {
48 : public:
49 : bool operator()(const std::shared_ptr<BString> &lhs,
50 : const std::shared_ptr<BString> &rhs) const;
51 : };
52 :
53 : private:
54 : /// Mapping of strings into items.
55 : // See the class description for the reason why a custom comparator is
56 : // used instead of @c std::less<>.
57 : using BItemMap = std::map<std::shared_ptr<BString>,
58 : std::shared_ptr<BItem>, BStringByValueComparator>;
59 :
60 : public:
61 : /// Key type.
62 : using key_type = BItemMap::key_type;
63 :
64 : /// Mapped type.
65 : using mapped_type = BItemMap::mapped_type;
66 :
67 : /// Value type.
68 : using value_type = BItemMap::value_type;
69 :
70 : /// Size type.
71 : using size_type = BItemMap::size_type;
72 :
73 : /// Reference.
74 : using reference = BItemMap::reference;
75 :
76 : /// Constant reference.
77 : using const_reference = BItemMap::const_reference;
78 :
79 : /// Iterator.
80 : using iterator = BItemMap::iterator;
81 :
82 : /// Constant iterator.
83 : using const_iterator = BItemMap::const_iterator;
84 :
85 : public:
86 : static std::unique_ptr<BDictionary> create();
87 : static std::unique_ptr<BDictionary> create(
88 : std::initializer_list<value_type> items);
89 :
90 : /// @name Capacity
91 : /// @{
92 : size_type size() const;
93 : bool empty() const;
94 : /// @}
95 :
96 : /// @name Element Access and Modifiers
97 : /// @{
98 : mapped_type &operator[](const key_type &key);
99 : /// @}
100 :
101 : /// @name Iterators
102 : /// @{
103 : iterator begin();
104 : iterator end();
105 : const_iterator begin() const;
106 : const_iterator end() const;
107 : const_iterator cbegin() const;
108 : const_iterator cend() const;
109 : /// @}
110 :
111 : /// @name BItemVisitor Support
112 : /// @{
113 : virtual void accept(BItemVisitor *visitor) override;
114 : /// @}
115 :
116 : private:
117 : BDictionary();
118 : explicit BDictionary(std::initializer_list<value_type> items);
119 :
120 : private:
121 : /// Underlying list of items.
122 : BItemMap itemMap;
123 : };
124 :
125 : } // namespace bencoding
126 :
127 : #endif
|