189a1d03eSRichard #ifndef STRUCTURES_H 289a1d03eSRichard #define STRUCTURES_H 389a1d03eSRichard 4*6a1f8ef8SChris Cotter namespace std { 5*6a1f8ef8SChris Cotter template <class T> constexpr auto begin(T& t) -> decltype(t.begin()); 6*6a1f8ef8SChris Cotter template <class T> constexpr auto begin(const T& t) -> decltype(t.begin()); 7*6a1f8ef8SChris Cotter template <class T> constexpr auto end(T& t) -> decltype(t.end()); 8*6a1f8ef8SChris Cotter template <class T> constexpr auto end(const T& t) -> decltype(t.end()); 9*6a1f8ef8SChris Cotter template <class T> constexpr auto size(const T& t) -> decltype(t.size()); 10*6a1f8ef8SChris Cotter } // namespace std 11*6a1f8ef8SChris Cotter 1289a1d03eSRichard extern "C" { 1389a1d03eSRichard extern int printf(const char *restrict, ...); 1489a1d03eSRichard } 1589a1d03eSRichard 1689a1d03eSRichard struct Val {int X; void g(); }; 1789a1d03eSRichard 1889a1d03eSRichard struct MutableVal { 1989a1d03eSRichard void constFun(int) const; 2089a1d03eSRichard void nonConstFun(int, int); 2189a1d03eSRichard void constFun(MutableVal &) const; 2289a1d03eSRichard void constParamFun(const MutableVal &) const; 2389a1d03eSRichard void nonConstParamFun(const MutableVal &); 2489a1d03eSRichard int X; 2589a1d03eSRichard }; 2689a1d03eSRichard 2789a1d03eSRichard struct NonTriviallyCopyable { 2889a1d03eSRichard NonTriviallyCopyable() = default; 2989a1d03eSRichard // Define this constructor to make this class non-trivially copyable. 3089a1d03eSRichard NonTriviallyCopyable(const NonTriviallyCopyable& Ntc); 3189a1d03eSRichard int X; 3289a1d03eSRichard }; 3389a1d03eSRichard 3489a1d03eSRichard struct TriviallyCopyableButBig { 3589a1d03eSRichard int X; 3689a1d03eSRichard char Array[16]; 3789a1d03eSRichard }; 3889a1d03eSRichard 39*6a1f8ef8SChris Cotter namespace ADT { 40*6a1f8ef8SChris Cotter 4189a1d03eSRichard struct S { 4289a1d03eSRichard typedef MutableVal *iterator; 4389a1d03eSRichard typedef const MutableVal *const_iterator; 4489a1d03eSRichard const_iterator begin() const; 4589a1d03eSRichard const_iterator end() const; 4689a1d03eSRichard const_iterator cbegin() const; 4789a1d03eSRichard const_iterator cend() const; 4889a1d03eSRichard iterator begin(); 4989a1d03eSRichard iterator end(); 5089a1d03eSRichard }; 5189a1d03eSRichard 52*6a1f8ef8SChris Cotter S::const_iterator begin(const S&); 53*6a1f8ef8SChris Cotter S::const_iterator end(const S&); 54*6a1f8ef8SChris Cotter S::const_iterator cbegin(const S&); 55*6a1f8ef8SChris Cotter S::const_iterator cend(const S&); 56*6a1f8ef8SChris Cotter S::iterator begin(S&); 57*6a1f8ef8SChris Cotter S::iterator end(S&); 58*6a1f8ef8SChris Cotter unsigned size(const S&); 59*6a1f8ef8SChris Cotter 6089a1d03eSRichard struct T { 6189a1d03eSRichard typedef int value_type; 6289a1d03eSRichard struct iterator { 6389a1d03eSRichard value_type &operator*(); 6489a1d03eSRichard const value_type &operator*() const; 6589a1d03eSRichard iterator& operator ++(); 6689a1d03eSRichard bool operator!=(const iterator &other); 6789a1d03eSRichard void insert(value_type); 6889a1d03eSRichard value_type X; 6989a1d03eSRichard }; 7089a1d03eSRichard iterator begin(); 7189a1d03eSRichard iterator end(); 7289a1d03eSRichard }; 73*6a1f8ef8SChris Cotter T::iterator begin(T&); 74*6a1f8ef8SChris Cotter T::iterator end(T&); 75*6a1f8ef8SChris Cotter 76*6a1f8ef8SChris Cotter } // namespace ADT 77*6a1f8ef8SChris Cotter 78*6a1f8ef8SChris Cotter using ADT::S; 79*6a1f8ef8SChris Cotter using ADT::T; 8089a1d03eSRichard 8189a1d03eSRichard struct Q { 8289a1d03eSRichard typedef int value_type; 8389a1d03eSRichard struct const_iterator { 8489a1d03eSRichard value_type &operator*(); 8589a1d03eSRichard const value_type &operator*() const; 8689a1d03eSRichard const_iterator &operator++(); 8789a1d03eSRichard bool operator!=(const const_iterator &other); 8889a1d03eSRichard void insert(value_type); 8989a1d03eSRichard value_type X; 9089a1d03eSRichard }; 9189a1d03eSRichard struct iterator { 9289a1d03eSRichard operator const_iterator() const; 9389a1d03eSRichard }; 9489a1d03eSRichard iterator begin(); 9589a1d03eSRichard iterator end(); 9689a1d03eSRichard }; 9789a1d03eSRichard 9889a1d03eSRichard struct U { 9989a1d03eSRichard struct iterator { 10089a1d03eSRichard Val& operator*(); 10189a1d03eSRichard const Val& operator*()const; 10289a1d03eSRichard iterator& operator ++(); 10389a1d03eSRichard bool operator!=(const iterator &other); 10489a1d03eSRichard Val *operator->(); 10589a1d03eSRichard }; 10689a1d03eSRichard iterator begin(); 10789a1d03eSRichard iterator end(); 10889a1d03eSRichard int X; 10989a1d03eSRichard }; 11089a1d03eSRichard 11189a1d03eSRichard struct X { 11289a1d03eSRichard S Ss; 11389a1d03eSRichard T Tt; 11489a1d03eSRichard U Uu; 11589a1d03eSRichard S getS(); 11689a1d03eSRichard }; 11789a1d03eSRichard 118*6a1f8ef8SChris Cotter namespace ADT { 119*6a1f8ef8SChris Cotter 12089a1d03eSRichard template<typename ElemType> 12189a1d03eSRichard class dependent { 12289a1d03eSRichard public: 12389a1d03eSRichard dependent<ElemType>(); 12489a1d03eSRichard struct iterator_base { 12589a1d03eSRichard const ElemType& operator*()const; 12689a1d03eSRichard iterator_base& operator ++(); 12789a1d03eSRichard bool operator!=(const iterator_base &other) const; 12889a1d03eSRichard const ElemType *operator->() const; 12989a1d03eSRichard }; 13089a1d03eSRichard 13189a1d03eSRichard struct iterator : iterator_base { 13289a1d03eSRichard ElemType& operator*(); 13389a1d03eSRichard iterator& operator ++(); 13489a1d03eSRichard ElemType *operator->(); 13589a1d03eSRichard }; 13689a1d03eSRichard 13789a1d03eSRichard typedef iterator_base const_iterator; 13889a1d03eSRichard const_iterator begin() const; 13989a1d03eSRichard const_iterator end() const; 14089a1d03eSRichard iterator begin(); 14189a1d03eSRichard iterator end(); 14289a1d03eSRichard unsigned size() const; 14389a1d03eSRichard ElemType & operator[](unsigned); 14489a1d03eSRichard const ElemType & operator[](unsigned) const; 14589a1d03eSRichard ElemType & at(unsigned); 14689a1d03eSRichard ElemType & at(unsigned, unsigned); 14789a1d03eSRichard const ElemType & at(unsigned) const; 14889a1d03eSRichard 14989a1d03eSRichard // Intentionally evil. 15089a1d03eSRichard dependent<ElemType> operator*(); 15189a1d03eSRichard 15289a1d03eSRichard void foo(); 15389a1d03eSRichard void constFoo() const; 15489a1d03eSRichard }; 15589a1d03eSRichard 156e4329520SChris Cotter template<typename ElemType> 157*6a1f8ef8SChris Cotter unsigned size(const dependent<ElemType>&); 158*6a1f8ef8SChris Cotter template<typename ElemType> 159*6a1f8ef8SChris Cotter unsigned length(const dependent<ElemType>&); 160*6a1f8ef8SChris Cotter 161*6a1f8ef8SChris Cotter template<typename ElemType> 162e4329520SChris Cotter class dependent_derived : public dependent<ElemType> { 163e4329520SChris Cotter }; 164e4329520SChris Cotter 165*6a1f8ef8SChris Cotter } // namespace ADT 166*6a1f8ef8SChris Cotter 167*6a1f8ef8SChris Cotter using ADT::dependent; 168*6a1f8ef8SChris Cotter using ADT::dependent_derived; 169*6a1f8ef8SChris Cotter 17089a1d03eSRichard template<typename First, typename Second> 17189a1d03eSRichard class doublyDependent{ 17289a1d03eSRichard public: 17389a1d03eSRichard struct Value { 17489a1d03eSRichard First first; 17589a1d03eSRichard Second second; 17689a1d03eSRichard }; 17789a1d03eSRichard 17889a1d03eSRichard struct iterator_base { 17989a1d03eSRichard const Value& operator*()const; 18089a1d03eSRichard iterator_base& operator ++(); 18189a1d03eSRichard bool operator!=(const iterator_base &other) const; 18289a1d03eSRichard const Value *operator->() const; 18389a1d03eSRichard }; 18489a1d03eSRichard 18589a1d03eSRichard struct iterator : iterator_base { 18689a1d03eSRichard Value& operator*(); 18789a1d03eSRichard Value& operator ++(); 18889a1d03eSRichard Value *operator->(); 18989a1d03eSRichard }; 19089a1d03eSRichard 19189a1d03eSRichard typedef iterator_base const_iterator; 19289a1d03eSRichard const_iterator begin() const; 19389a1d03eSRichard const_iterator end() const; 19489a1d03eSRichard iterator begin(); 19589a1d03eSRichard iterator end(); 19689a1d03eSRichard }; 19789a1d03eSRichard 19889a1d03eSRichard template<typename Contained> 19989a1d03eSRichard class transparent { 20089a1d03eSRichard public: 20189a1d03eSRichard Contained *at(); 20289a1d03eSRichard Contained *operator->(); 20389a1d03eSRichard Contained operator*(); 20489a1d03eSRichard }; 20589a1d03eSRichard 20689a1d03eSRichard template<typename IteratorType> 20789a1d03eSRichard struct Nested { 20889a1d03eSRichard typedef IteratorType* iterator; 20989a1d03eSRichard typedef const IteratorType* const_iterator; 21089a1d03eSRichard IteratorType *operator->(); 21189a1d03eSRichard IteratorType operator*(); 21289a1d03eSRichard iterator begin(); 21389a1d03eSRichard iterator end(); 21489a1d03eSRichard const_iterator begin() const; 21589a1d03eSRichard const_iterator end() const; 21689a1d03eSRichard }; 21789a1d03eSRichard 21889a1d03eSRichard // Like llvm::SmallPtrSet, the iterator has a dereference operator that returns 21989a1d03eSRichard // by value instead of by reference. 22089a1d03eSRichard template <typename T> 22189a1d03eSRichard struct PtrSet { 22289a1d03eSRichard struct iterator { 22389a1d03eSRichard bool operator!=(const iterator &other) const; 22489a1d03eSRichard const T operator*(); 22589a1d03eSRichard iterator &operator++(); 22689a1d03eSRichard }; 22789a1d03eSRichard iterator begin() const; 22889a1d03eSRichard iterator end() const; 22989a1d03eSRichard }; 23089a1d03eSRichard 23189a1d03eSRichard template <typename T> 23289a1d03eSRichard struct TypedefDerefContainer { 23389a1d03eSRichard struct iterator { 23489a1d03eSRichard typedef T &deref_type; 23589a1d03eSRichard bool operator!=(const iterator &other) const; 23689a1d03eSRichard deref_type operator*(); 23789a1d03eSRichard iterator &operator++(); 23889a1d03eSRichard }; 23989a1d03eSRichard iterator begin() const; 24089a1d03eSRichard iterator end() const; 24189a1d03eSRichard }; 24289a1d03eSRichard 24389a1d03eSRichard template <typename T> 24489a1d03eSRichard struct RValueDerefContainer { 24589a1d03eSRichard struct iterator { 24689a1d03eSRichard typedef T &&deref_type; 24789a1d03eSRichard bool operator!=(const iterator &other) const; 24889a1d03eSRichard deref_type operator*(); 24989a1d03eSRichard iterator &operator++(); 25089a1d03eSRichard }; 25189a1d03eSRichard iterator begin() const; 25289a1d03eSRichard iterator end() const; 25389a1d03eSRichard }; 25489a1d03eSRichard 25589a1d03eSRichard namespace Macros { 25689a1d03eSRichard 25789a1d03eSRichard struct MacroStruct { 25889a1d03eSRichard int Arr[10]; 25989a1d03eSRichard }; 26089a1d03eSRichard static MacroStruct *MacroSt; 26189a1d03eSRichard #define CONT MacroSt-> 26289a1d03eSRichard 26389a1d03eSRichard } // namespace Macros 26489a1d03eSRichard 26589a1d03eSRichard #endif // STRUCTURES_H 266