libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers char_array_formatter.hpp Source File

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