| /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. |
| * Use of this file is governed by the BSD 3-clause license that |
| * can be found in the LICENSE.txt file in the project root. |
| */ |
| |
| #pragma once |
| |
| #include "antlr4-common.h" |
| |
| namespace antlrcpp { |
| |
| std::string join(std::vector<std::string> strings, const std::string &separator); |
| std::map<std::string, size_t> toMap(const std::vector<std::string> &keys); |
| std::string escapeWhitespace(std::string str, bool escapeSpaces); |
| std::string toHexString(const int t); |
| std::string arrayToString(const std::vector<std::string> &data); |
| std::string replaceString(const std::string &s, const std::string &from, const std::string &to); |
| std::vector<std::string> split(const std::string &s, const std::string &sep, int count); |
| std::string indent(const std::string &s, const std::string &indentation, bool includingFirst = true); |
| |
| // Using RAII + a lambda to implement a "finally" replacement. |
| template <typename OnEnd> |
| struct FinalAction { |
| FinalAction(OnEnd f) : _cleanUp { std::move(f) } {} |
| FinalAction(FinalAction &&other) : |
| _cleanUp(std::move(other._cleanUp)), _enabled(other._enabled) { |
| other._enabled = false; // Don't trigger the lambda after ownership has moved. |
| } |
| ~FinalAction() { if (_enabled) _cleanUp(); } |
| |
| void disable() { _enabled = false; } |
| private: |
| OnEnd _cleanUp; |
| bool _enabled {true}; |
| }; |
| |
| template <typename OnEnd> |
| FinalAction<OnEnd> finally(OnEnd f) { |
| return FinalAction<OnEnd>(std::move(f)); |
| } |
| |
| // Convenience functions to avoid lengthy dynamic_cast() != nullptr checks in many places. |
| template <typename T1, typename T2> |
| inline bool is(T2 *obj) { // For pointer types. |
| return dynamic_cast<typename std::add_const<T1>::type>(obj) != nullptr; |
| } |
| |
| template <typename T1, typename T2> |
| inline bool is(Ref<T2> const& obj) { // For shared pointers. |
| return dynamic_cast<T1 *>(obj.get()) != nullptr; |
| } |
| |
| template <typename T> |
| std::string toString(const T &o) { |
| std::stringstream ss; |
| // typeid gives the mangled class name, but that's all what's possible |
| // in a portable way. |
| ss << typeid(o).name() << "@" << std::hex << reinterpret_cast<uintptr_t>(&o); |
| return ss.str(); |
| } |
| |
| // Get the error text from an exception pointer or the current exception. |
| std::string what(std::exception_ptr eptr = std::current_exception()); |
| |
| class SingleWriteMultipleReadLock { |
| public: |
| void readLock(); |
| void readUnlock(); |
| void writeLock(); |
| void writeUnlock(); |
| |
| private: |
| std::condition_variable _readerGate; |
| std::condition_variable _writerGate; |
| |
| std::mutex _mutex; |
| size_t _activeReaders = 0; |
| size_t _waitingWriters = 0; |
| size_t _activeWriters = 0; |
| }; |
| |
| } // namespace antlrcpp |