1 //===- StringEntry.h ------------------------------------------------------===//
2 //
3 //                     The MCLinker Project
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #ifndef MCLD_ADT_STRINGENTRY_H_
10 #define MCLD_ADT_STRINGENTRY_H_
11 
12 #include <llvm/ADT/StringRef.h>
13 #include <llvm/Support/DataTypes.h>
14 
15 #include <cassert>
16 #include <cstdlib>
17 #include <cstring>
18 
19 namespace mcld {
20 template <typename DataType>
21 class StringEntryFactory;
22 
23 /** \class StringEntry
24  *  \brief StringEntry is a pair of strings which is designed for high locality.
25  */
26 template <typename DataType>
27 class StringEntry {
28  public:
29   typedef llvm::StringRef key_type;
30   typedef DataType value_type;
31 
32  public:
key()33   key_type key() { return key_type(m_Key, m_KeyLen); }
34 
key()35   const key_type key() const { return key_type(m_Key, m_KeyLen); }
36 
value()37   value_type& value() { return m_Value; }
38 
value()39   const value_type& value() const { return m_Value; }
40 
getKeyLength()41   size_t getKeyLength() const { return m_KeyLen; }
42 
getValueLength()43   size_t getValueLength() const { return m_Value.size(); }
44 
setValue(const DataType & pVal)45   void setValue(const DataType& pVal) { m_Value = pVal; }
46 
compare(const llvm::StringRef & pX)47   bool compare(const llvm::StringRef& pX) { return key().equals(pX); }
48 
compare(const llvm::StringRef & pX)49   bool compare(const llvm::StringRef& pX) const { return key().equals(pX); }
50 
51  private:
52   StringEntry();
53   explicit StringEntry(const key_type& pKey);
54   StringEntry(const StringEntry& pCopy);
55   ~StringEntry();
56 
57  private:
58   DataType m_Value;
59   uint16_t m_KeyLen;
60   char m_Key[];
61 
62   friend class StringEntryFactory<DataType>;
63 };
64 
65 template <>
66 class StringEntry<llvm::StringRef> {
67  public:
68   typedef llvm::StringRef key_type;
69   typedef llvm::StringRef value_type;
70 
71  public:
key()72   key_type key() { return key_type(m_Key, m_KeyLen); }
73 
key()74   const key_type key() const { return key_type(m_Key, m_KeyLen); }
75 
value()76   value_type& value() { return m_Value; }
77 
value()78   const value_type& value() const { return m_Value; }
79 
getKeyLength()80   size_t getKeyLength() const { return m_KeyLen; }
81 
getValueLength()82   size_t getValueLength() const { return m_Value.size(); }
83 
setValue(const std::string & pVal)84   void setValue(const std::string& pVal) { setValue(pVal.c_str()); }
85 
86   void setValue(const char* pVal);
87 
88   void setValue(llvm::StringRef pVal);
89 
compare(const llvm::StringRef pX)90   bool compare(const llvm::StringRef pX) { return key().equals(pX); }
91 
compare(const llvm::StringRef pX)92   bool compare(const llvm::StringRef pX) const { return key().equals(pX); }
93 
94  private:
95   StringEntry();
96   explicit StringEntry(const key_type& pKey);
97   StringEntry(const StringEntry& pCopy);
98   ~StringEntry();
99 
100  private:
101   llvm::StringRef m_Value;
102   uint16_t m_KeyLen;
103   char m_Key[];
104 
105   friend class StringEntryFactory<llvm::StringRef>;
106 };
107 
108 template <typename DataType>
109 class StringEntryFactory {
110  public:
111   typedef StringEntry<DataType> entry_type;
112   typedef typename StringEntry<DataType>::key_type key_type;
113   typedef typename StringEntry<DataType>::value_type value_type;
114 
115  public:
116   StringEntryFactory();
117   ~StringEntryFactory();
118 
119   StringEntry<DataType>* produce(const key_type& pKey);
120   void destroy(StringEntry<DataType>* pEntry);
121 };
122 
123 #include "StringEntry.tcc"
124 
125 }  // namespace mcld
126 
127 #endif  // MCLD_ADT_STRINGENTRY_H_
128