Ed Tanous | 50c50c2 | 2017-05-12 16:58:06 -0700 | [diff] [blame^] | 1 | /** ========================================================================== |
| 2 | * 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes |
| 3 | * with no warranties. This code is yours to share, use and modify with no |
| 4 | * strings attached and no restrictions or obligations. |
| 5 | * |
| 6 | * For more information see g3log/LICENSE or refer refer to http://unlicense.org |
| 7 | * ============================================================================*/ |
| 8 | |
| 9 | #include "g3log/loglevels.hpp" |
| 10 | #include <atomic> |
| 11 | #include <cassert> |
| 12 | #include <map> |
| 13 | |
| 14 | namespace { |
| 15 | namespace { |
| 16 | /// As suggested in: http://stackoverflow.com/questions/13193484/how-to-declare-a-vector-of-atomic-in-c |
| 17 | struct atomicbool { |
| 18 | private: |
| 19 | std::atomic<bool> value_; |
| 20 | public: |
| 21 | atomicbool(): value_ {false} {} |
| 22 | atomicbool(const bool &value): value_ {value} {} |
| 23 | atomicbool(const std::atomic<bool> &value) : value_ {value.load(std::memory_order_acquire)} {} |
| 24 | atomicbool(const atomicbool &other): value_ {other.value_.load(std::memory_order_acquire)} {} |
| 25 | atomicbool &operator=(const atomicbool &other) { |
| 26 | value_.store(other.value_.load(std::memory_order_acquire), std::memory_order_release); |
| 27 | return *this; |
| 28 | } |
| 29 | bool value() {return value_.load(std::memory_order_acquire);} |
| 30 | std::atomic<bool>& get() {return value_;} |
| 31 | }; |
| 32 | |
| 33 | } // anonymous |
| 34 | |
| 35 | } |
| 36 | namespace g3 { |
| 37 | namespace internal { |
| 38 | bool wasFatal(const LEVELS &level) { |
| 39 | return level.value >= FATAL.value; |
| 40 | } |
| 41 | |
| 42 | #ifdef G3_DYNAMIC_LOGGING |
| 43 | std::map<int, atomicbool> g_log_level_status = {{g3::kDebugValue, true}, {INFO.value, true}, {WARNING.value, true}, {FATAL.value, true}}; |
| 44 | #endif |
| 45 | } // internal |
| 46 | |
| 47 | #ifdef G3_DYNAMIC_LOGGING |
| 48 | namespace only_change_at_initialization { |
| 49 | void setLogLevel(LEVELS log_level, bool enabled) { |
| 50 | int level = log_level.value; |
| 51 | internal::g_log_level_status[level].get().store(enabled, std::memory_order_release); |
| 52 | } |
| 53 | |
| 54 | std::string printLevels() { |
| 55 | std::string levels; |
| 56 | for (auto& v : internal::g_log_level_status) { |
| 57 | levels += "value: " + std::to_string(v.first) + " status: " + std::to_string(v.second.value()) + "\n"; |
| 58 | } |
| 59 | return levels; |
| 60 | } |
| 61 | |
| 62 | void reset() { |
| 63 | internal::g_log_level_status.clear(); |
| 64 | internal::g_log_level_status = std::map<int, atomicbool>{{g3::kDebugValue, true}, {INFO.value, true}, {WARNING.value, true}, {FATAL.value, true}}; |
| 65 | } |
| 66 | } // only_change_at_initialization |
| 67 | #endif |
| 68 | |
| 69 | bool logLevel(LEVELS log_level) { |
| 70 | #ifdef G3_DYNAMIC_LOGGING |
| 71 | int level = log_level.value; |
| 72 | bool status = internal::g_log_level_status[level].value(); |
| 73 | return status; |
| 74 | #endif |
| 75 | return true; |
| 76 | } |
| 77 | } // g3 |