libuav original
Dependents: UAVCAN UAVCAN_Subscriber
char_array_formatter.hpp
00001 /* 00002 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com> 00003 */ 00004 00005 #ifndef UAVCAN_MARSHAL_CHAR_ARRAY_FORMATTER_HPP_INCLUDED 00006 #define UAVCAN_MARSHAL_CHAR_ARRAY_FORMATTER_HPP_INCLUDED 00007 00008 #include <uavcan/build_config.hpp> 00009 #include <uavcan/marshal/array.hpp> 00010 00011 #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11) 00012 # error UAVCAN_CPP_VERSION 00013 #endif 00014 00015 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 00016 # include <type_traits> 00017 #endif 00018 00019 namespace uavcan 00020 { 00021 00022 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11 00023 00024 template <typename ArrayType_> 00025 class UAVCAN_EXPORT CharArrayFormatter 00026 { 00027 ArrayType_& array_; 00028 00029 template <typename T> 00030 typename std::enable_if<std::is_floating_point<T>::value>::type 00031 writeValue(T value) 00032 { 00033 array_.template appendFormatted<double>("%g", double(value)); 00034 } 00035 00036 template <typename T> 00037 typename std::enable_if<std::is_integral<T>::value>::type 00038 writeValue(T value) 00039 { 00040 if (std::is_same<T, char>()) 00041 { 00042 if (array_.size() != array_.capacity()) 00043 { 00044 array_.push_back(typename ArrayType_::ValueType(value)); 00045 } 00046 } 00047 else if (std::is_signed<T>()) 00048 { 00049 array_.template appendFormatted<long long>("%lli", static_cast<long long>(value)); 00050 } 00051 else 00052 { 00053 array_.template appendFormatted<unsigned long long>("%llu", static_cast<unsigned long long>(value)); 00054 } 00055 } 00056 00057 template <typename T> 00058 typename std::enable_if<std::is_pointer<T>::value && !std::is_same<T, const char*>::value>::type 00059 writeValue(T value) 00060 { 00061 array_.template appendFormatted<const void*>("%p", static_cast<const void*>(value)); 00062 } 00063 00064 void writeValue(const char* value) 00065 { 00066 array_.template appendFormatted<const char*>("%s", value); 00067 } 00068 00069 public: 00070 typedef ArrayType_ ArrayType; 00071 00072 explicit CharArrayFormatter(ArrayType& array) 00073 : array_(array) 00074 { } 00075 00076 ArrayType& getArray() { return array_; } 00077 const ArrayType& getArray() const { return array_; } 00078 00079 void write(const char* text) 00080 { 00081 writeValue(text); 00082 } 00083 00084 template <typename T, typename... Args> 00085 void write(const char* s, T value, Args... args) 00086 { 00087 while (s && *s) 00088 { 00089 if (*s == '%') 00090 { 00091 s += 1; 00092 if (*s != '%') 00093 { 00094 writeValue(value); 00095 write(++s, args...); 00096 break; 00097 } 00098 } 00099 writeValue(*s++); 00100 } 00101 } 00102 }; 00103 00104 #else 00105 00106 template <typename ArrayType_> 00107 class UAVCAN_EXPORT CharArrayFormatter 00108 { 00109 ArrayType_& array_; 00110 00111 public: 00112 typedef ArrayType_ ArrayType; 00113 00114 CharArrayFormatter(ArrayType& array) 00115 : array_(array) 00116 { } 00117 00118 ArrayType& getArray() { return array_; } 00119 const ArrayType& getArray() const { return array_; } 00120 00121 void write(const char* const text) 00122 { 00123 array_.template appendFormatted<const char*>("%s", text); 00124 } 00125 00126 /** 00127 * This version does not support more than one formatted argument, though it can be improved. 00128 * And it is unsafe. 00129 * There is typesafe version for C++11 above. 00130 */ 00131 template <typename A> 00132 void write(const char* const format, const A value) 00133 { 00134 array_.template appendFormatted<A>(format, value); 00135 } 00136 }; 00137 00138 #endif 00139 00140 } 00141 00142 #endif // UAVCAN_MARSHAL_CHAR_ARRAY_FORMATTER_HPP_INCLUDED
Generated on Tue Jul 12 2022 17:17:30 by 1.7.2