Przeglądaj źródła

Adding clang-format settings.

Sam Jaffe 7 lat temu
rodzic
commit
3b7d0d2641

+ 108 - 0
.clang-format

@@ -0,0 +1,108 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: true
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:   
+  AfterClass:      false
+  AfterControlStatement: false
+  AfterEnum:       false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeInheritanceComma: false
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializers: BeforeColon
+BreakAfterJavaFieldAnnotations: false
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: false
+ForEachMacros:   
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IncludeCategories: 
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+  - Regex:           '.*'
+    Priority:        1
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: false
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: All
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Middle
+ReflowComments:  true
+SortIncludes:    true
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterTemplateKeyword: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        8
+UseTab:          Never
+...
+

+ 18 - 19
include/json/binder/json_binder.hpp

@@ -4,36 +4,35 @@
 
 #include <iostream>
 
-namespace json {  namespace binder {
-  template <typename T>
-  class binder_impl {
+namespace json { namespace binder {
+  template <typename T> class binder_impl {
   public:
-    virtual binder_impl<T>* clone() const = 0;
+    virtual binder_impl<T> * clone() const = 0;
     virtual ~binder_impl() {}
-    virtual void parse(T&, char const*&, parser::options) const = 0;
-    virtual void write(T const&, std::ostream &) const = 0;
+    virtual void parse(T &, char const *&, parser::options) const = 0;
+    virtual void write(T const &, std::ostream &) const = 0;
   };
-  
-  template <typename T>
-  class binder {
+
+  template <typename T> class binder {
   public:
     binder() : impl(nullptr) {}
-    binder(binder const& other) : impl(other.impl->clone()) {}
-    binder(binder_impl<T> const* p) : impl(p) {}
-    binder(binder_impl<T> const& r) : impl(r.clone()) {}
-    
+    binder(binder const & other) : impl(other.impl->clone()) {}
+    binder(binder_impl<T> const * p) : impl(p) {}
+    binder(binder_impl<T> const & r) : impl(r.clone()) {}
+
     ~binder() { delete impl; }
-    
-    void parse(T& object, char const*& data, parser::options opts) const {
+
+    void parse(T & object, char const *& data, parser::options opts) const {
       if (!impl) return; // error?
       impl->parse(object, data, opts);
     }
-    
-    void write(T const& object, std::ostream & data) const {
+
+    void write(T const & object, std::ostream & data) const {
       if (!impl) return; // error?
       impl->write(object, data);
     }
+
   private:
-    binder_impl<T> const* impl;
+    binder_impl<T> const * impl;
   };
-} }
+}}

+ 1 - 1
include/json/binder/json_binder_discard.hpp

@@ -8,5 +8,5 @@
 #pragma once
 
 namespace json {
-  void parse_discard_token( char const * & data );
+  void parse_discard_token(char const *& data);
 }

+ 12 - 10
include/json/binder/json_binder_parser.hpp

@@ -17,21 +17,23 @@
 
 namespace json {
   class value;
-  
-  namespace binder { template <typename, typename> class visitor; }
-  
+
+  namespace binder {
+    template <typename, typename> class visitor;
+  }
+
   namespace parser {
     template <typename T, typename S>
-    void parse(binder::visitor<T, S>&, char const*, options opts = allow_all);
-    
+    void parse(binder::visitor<T, S> &, char const *, options opts = allow_all);
+
     template <typename T, typename S>
-    void parse(binder::visitor<T, S>&& v, std::string const& s,
+    void parse(binder::visitor<T, S> && v, std::string const & s,
                options opts = allow_all) {
-      parse(static_cast<binder::visitor<T, S>&>(v), s.c_str(), opts);
+      parse(static_cast<binder::visitor<T, S> &>(v), s.c_str(), opts);
     }
-    
+
     template <typename T, typename S>
-    void parse(binder::visitor<T, S>&& v, std::istream & in,
+    void parse(binder::visitor<T, S> && v, std::istream & in,
                options opts = allow_all) {
       if (!in) return;
       in.seekg(0, std::ios_base::end);
@@ -39,7 +41,7 @@ namespace json {
       std::unique_ptr<char[]> data{new char[end]};
       in.seekg(0);
       in.read(data.get(), end);
-      parse(static_cast<binder::visitor<T, S>&>(v), data.get(), opts);
+      parse(static_cast<binder::visitor<T, S> &>(v), data.get(), opts);
     }
   }
 }

+ 14 - 18
include/json/binder/json_binder_visitor.hpp

@@ -8,39 +8,35 @@
 #include <sstream>
 
 namespace json { namespace binder {
-  template <typename T, typename S = T>
-  class visitor {
+  template <typename T, typename S = T> class visitor {
   public:
-    visitor(S& o, binder_impl<T>& b) : obj(o), b(b) {}
+    visitor(S & o, binder_impl<T> & b) : obj(o), b(b) {}
 
-    void parse(char const* data, parser::options opts) {
+    void parse(char const * data, parser::options opts) {
       b.parse(obj, data, opts);
-      if ( json::helper::get_next_element(data)
-          && opts & parser::disable_concatenated_json_bodies ) {
+      if (json::helper::get_next_element(data) &&
+          opts & parser::disable_concatenated_json_bodies) {
         throw malformed_json_exception{
-          "Config set to require json input be terminated"
-        };
+            "Config set to require json input be terminated"};
       }
     }
 
-    void write(std::ostream & data) const {
-      b.write(obj, data);
-    }
+    void write(std::ostream & data) const { b.write(obj, data); }
 
-    private:
-      S& obj;
-      binder_impl<T>& b;
+  private:
+    S & obj;
+    binder_impl<T> & b;
   };
 
   template <typename T, typename S>
-  visitor<T, S> bind(S& object, binder_impl<T>& b) {
+  visitor<T, S> bind(S & object, binder_impl<T> & b) {
     return {object, b};
   }
-} }
+}}
 
 namespace json { namespace parser {
   template <typename T>
-  void parse(binder::visitor<T>& visitor, char const* data,
+  void parse(binder::visitor<T> & visitor, char const * data,
              options opts = allow_all) {
     visitor.parse(data, opts);
   }
@@ -56,4 +52,4 @@ namespace json { namespace parser {
     visitor.write(ss);
     data = ss.str();
   }
-} }
+}}

+ 21 - 22
include/json/binder/json_direct_binder.hpp

@@ -10,58 +10,57 @@
 #include "json_binder.hpp"
 
 namespace json { namespace binder {
-  template <typename T, typename E, typename = void>
-  class direct_binder;
-  
+  template <typename T, typename E, typename = void> class direct_binder;
+
   template <typename T, typename E, typename = void>
   class forward_binder : public binder_impl<T> {
   public:
-    forward_binder(E T::*p, binder<E> const& i) :
-    ptr(p), impl(i) {
-    }
-    
-    virtual binder_impl<T>* clone() const override {
+    forward_binder(E T::*p, binder<E> const & i) : ptr(p), impl(i) {}
+
+    virtual binder_impl<T> * clone() const override {
       return new forward_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options opts) const override {
       impl.parse(val.*ptr, data, opts);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       impl.write(val.*ptr, data);
     }
+
   private:
     E T::*ptr;
     binder<E> impl;
   };
-  
-  template <typename T>
-  class value_binder : public binder_impl<T> {
+
+  template <typename T> class value_binder : public binder_impl<T> {
   private:
     struct detail {
       T value;
     };
+
   public:
     template <typename... Args>
     value_binder(Args &&... args) : impl(&detail::value, args...) {}
-    
-    virtual binder_impl<T>* clone() const override {
+
+    virtual binder_impl<T> * clone() const override {
       return new value_binder(*this);
     }
-    
-    virtual void parse(T & val, char const *&data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options opts) const override {
       detail tmp;
       impl.parse(tmp, data, opts);
       val = std::move(tmp.value);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       impl.write({val}, data);
     }
+
   private:
     direct_binder<detail, T> impl;
   };
-} }
+}}

+ 71 - 78
include/json/binder/json_direct_get_binder.hpp

@@ -19,33 +19,33 @@ namespace json { namespace binder {
   class get_binder : public binder_impl<T> {
     // Maybe a reference type
     using ith_type = decltype(std::get<I>(std::declval<T>()));
+
   public:
     using value_type = typename std::remove_reference<ith_type>::type;
-    
+
     get_binder() : impl(value_binder<value_type>()) {}
-    
-    get_binder(binder<value_type> val_binder)
-    : impl(std::move(val_binder)) {}
-    
-    get_binder(binder_impl<value_type> const & val_binder)
-    : impl(val_binder) {}
-    
-    virtual binder_impl<T>* clone() const override {
+
+    get_binder(binder<value_type> val_binder) : impl(std::move(val_binder)) {}
+
+    get_binder(binder_impl<value_type> const & val_binder) : impl(val_binder) {}
+
+    virtual binder_impl<T> * clone() const override {
       return new get_binder(*this);
     }
-    
-    virtual void parse(T& object, char const*& data,
+
+    virtual void parse(T & object, char const *& data,
                        parser::options opts) const override {
       impl.parse(std::get<I>(object), data, opts);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       impl.write(std::get<I>(val), data);
     }
+
   private:
     binder<value_type> impl;
   };
-  
+
 #if __cpluscplus >= 201402L
   namespace detail {
     template <typename TupleOut, typename TupleIn, std::size_t... Indexes>
@@ -53,141 +53,134 @@ namespace json { namespace binder {
                                              std::index_sequence<Indexes...>) {
       tuple_binder<TupleOut> binder;
       using swallow = int[];
-      (void) swallow{
-        0,
-        (void(binder(get_binder<TupleOut, Indexes>(std::get<Indexes>(binds)))),
-         0)...
-      };
+      (void)swallow{0, (void(binder(get_binder<TupleOut, Indexes>(
+                            std::get<Indexes>(binds)))),
+                        0)...};
       return binder;
     }
-    
+
     template <typename TupleOut, typename T, std::size_t... Indexes>
     tuple_binder<TupleOut> make_array_binder(binder<T> && binds,
                                              std::index_sequence<Indexes...>) {
       tuple_binder<TupleOut> binder;
       using swallow = int[];
-      (void) swallow{
-        0,
-        (void(binder(get_binder<TupleOut, Indexes>(binds))), 0)...
-      };
+      (void)swallow{0,
+                    (void(binder(get_binder<TupleOut, Indexes>(binds))), 0)...};
       return binder;
     }
   }
-  
+
   template <typename... Ts>
   tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder<Ts> &&... binds) {
-    return detail::make_tuple_binder<std::tuple<Ts...>>
-    (std::make_tuple(binds...),
-     std::make_index_sequence<sizeof...(Ts)>());
+    return detail::make_tuple_binder<std::tuple<Ts...>>(
+        std::make_tuple(binds...), std::make_index_sequence<sizeof...(Ts)>());
   }
 
   template <typename... Ts>
-  tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder_impl<Ts> &&... binds) {
-    return detail::make_tuple_binder<std::tuple<Ts...>>
-    (std::make_tuple(binder<Ts>(binds)...),
-     std::make_index_sequence<sizeof...(Ts)>());
+  tuple_binder<std::tuple<Ts...>>
+  make_tuple_binder(binder_impl<Ts> &&... binds) {
+    return detail::make_tuple_binder<std::tuple<Ts...>>(
+        std::make_tuple(binder<Ts>(binds)...),
+        std::make_index_sequence<sizeof...(Ts)>());
   }
-  
+
   template <typename... Ts>
   tuple_binder<std::tuple<Ts...>> make_default_tuple_binder() {
-    return detail::make_tuple_binder<std::tuple<Ts...>>
-    (std::make_tuple(binder<Ts>(value_binder<Ts>())...),
-     std::make_index_sequence<sizeof...(Ts)>());
+    return detail::make_tuple_binder<std::tuple<Ts...>>(
+        std::make_tuple(binder<Ts>(value_binder<Ts>())...),
+        std::make_index_sequence<sizeof...(Ts)>());
   }
-  
+
   template <typename T, std::size_t N>
   tuple_binder<std::array<T, N>> make_array_binder(binder<T> && binds) {
-    return detail::make_array_binder<std::array<T, N>>
-    (binds, std::make_index_sequence<N>());
+    return detail::make_array_binder<std::array<T, N>>(
+        binds, std::make_index_sequence<N>());
   }
-  
+
   template <typename T, std::size_t N>
-  tuple_binder<std::array<T, N>> make_array_binder(binder_impl<T> const & binds
-                                                   = value_binder<T>()) {
-    return detail::make_array_binder<std::array<T, N>>
-    (binder<T>(binds), std::make_index_sequence<N>());
+  tuple_binder<std::array<T, N>>
+  make_array_binder(binder_impl<T> const & binds = value_binder<T>()) {
+    return detail::make_array_binder<std::array<T, N>>(
+        binder<T>(binds), std::make_index_sequence<N>());
   }
 #else
   namespace detail {
     template <std::size_t> struct tuple_binder_helper;
-    
-    template <>
-    struct tuple_binder_helper<0> {
+
+    template <> struct tuple_binder_helper<0> {
       template <typename BindOut>
       tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind) const {
         return bind;
       }
     };
-    
-    template <std::size_t N>
-    struct tuple_binder_helper {
+
+    template <std::size_t N> struct tuple_binder_helper {
       template <typename BindOut, typename BindIn, typename... Ts>
       tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
                                          BindIn && ith,
                                          Ts &&... binders) const {
-        constexpr auto get_index = std::tuple_size<BindOut>::value-N;
+        constexpr auto get_index = std::tuple_size<BindOut>::value - N;
         using get_binder_t = get_binder<BindOut, get_index>;
-        return tuple_binder_helper<N-1>()
-        (bind(get_binder_t(std::forward<BindIn>(ith))),
-         std::forward<Ts>(binders)...);
+        return tuple_binder_helper<N - 1>()(
+            bind(get_binder_t(std::forward<BindIn>(ith))),
+            std::forward<Ts>(binders)...);
       }
     };
-    
+
     template <std::size_t> struct array_binder_helper;
-    
-    template <>
-    struct array_binder_helper<1> {
+
+    template <> struct array_binder_helper<1> {
       template <typename BindOut, typename BindIn>
       tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
                                          BindIn &&) const {
         return bind;
       }
     };
-    
-    template <std::size_t N>
-    struct array_binder_helper {
+
+    template <std::size_t N> struct array_binder_helper {
       template <typename BindOut, typename BindIn>
       tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
                                          BindIn && ith) const {
-        return array_binder_helper<N-1>()(bind(get_binder<BindOut, N-1>(ith)),
-                                          std::forward<BindIn>(ith));
+        return array_binder_helper<N - 1>()(
+            bind(get_binder<BindOut, N - 1>(ith)), std::forward<BindIn>(ith));
       }
     };
   }
-  
+
   template <typename... Ts>
   tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder<Ts> &&... binds) {
     tuple_binder<std::tuple<Ts...>> binder;
-    return detail::tuple_binder_helper<sizeof...(Ts)>()
-    (binder, std::forward<Ts>(binds)...);
+    return detail::tuple_binder_helper<sizeof...(Ts)>()(
+        binder, std::forward<Ts>(binds)...);
   }
-  
+
   template <typename... Ts>
-  tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder_impl<Ts> &&... binds) {
+  tuple_binder<std::tuple<Ts...>>
+  make_tuple_binder(binder_impl<Ts> &&... binds) {
     tuple_binder<std::tuple<Ts...>> binder;
-    return detail::tuple_binder_helper<sizeof...(Ts)>()
-    (binder, json::binder::binder<Ts>(binds)...);
+    return detail::tuple_binder_helper<sizeof...(Ts)>()(
+        binder, json::binder::binder<Ts>(binds)...);
   }
-  
+
   template <typename... Ts>
   tuple_binder<std::tuple<Ts...>> make_default_tuple_binder() {
     tuple_binder<std::tuple<Ts...>> binder;
-    return detail::tuple_binder_helper<sizeof...(Ts)>()
-    (binder, json::binder::binder<Ts>(value_binder<Ts>())...);
+    return detail::tuple_binder_helper<sizeof...(Ts)>()(
+        binder, json::binder::binder<Ts>(value_binder<Ts>())...);
   }
-  
+
   template <typename T, std::size_t N>
   tuple_binder<std::array<T, N>> make_array_binder(binder<T> && binds) {
     tuple_binder<std::array<T, N>> binder;
     return detail::array_binder_helper<N>(binder, binds);
   }
-  
+
   template <typename T, std::size_t N>
-  tuple_binder<std::array<T, N>> make_array_binder(binder_impl<T> const & binds
-                                                   = value_binder<T>()) {
+  tuple_binder<std::array<T, N>>
+  make_array_binder(binder_impl<T> const & binds = value_binder<T>()) {
     tuple_binder<std::array<T, N>> binder;
     return detail::array_binder_helper<N>(binder,
                                           json::binder::binder<T>(binds));
   }
 #endif
-} }
+}}

+ 22 - 18
include/json/binder/json_direct_map_binder.hpp

@@ -18,18 +18,18 @@ namespace json { namespace binder {
   public:
     associative_binder(C T::*p) : ptr(p), impl(value_binder<V>()) {}
     associative_binder(C T::*p, binder<V> const & i) : ptr(p), impl(i) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new associative_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options opts) const override {
       const char ch = json::helper::get_next_element(data);
       if (ch != '{') {
         throw json::malformed_json_exception("Expected an object type");
       }
       ++data;
-      
+
       V to_make;
       C & map = val.*ptr;
       std::string key;
@@ -42,11 +42,13 @@ namespace json { namespace binder {
         map.emplace(key, std::move(to_make));
         json::helper::advance_to_boundary('}', data);
       }
-      if (*data) ++data;
-      else throw unterminated_json_array();
+      if (*data)
+        ++data;
+      else
+        throw unterminated_json_array();
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << '{';
       std::map<std::string, V> const & map = val.*ptr;
       auto it = map.begin(), end = map.end();
@@ -61,19 +63,21 @@ namespace json { namespace binder {
       }
       data << '}';
     }
+
   private:
     std::map<std::string, V> T::*ptr;
     binder<V> impl;
   };
-  
-#define ASSOCIATIVE_DIRECT_BINDER( C ) \
-  template <typename T, typename V, typename... O> \
-  class direct_binder<T, C<std::string, V, O...> > : \
-  public associative_binder<T, V, C<std::string, V, O...>> { \
-  public: \
-    using associative_binder<T,V,C<std::string,V,O...>>::associative_binder; \
+
+#define ASSOCIATIVE_DIRECT_BINDER(C)                                           \
+  template <typename T, typename V, typename... O>                             \
+  class direct_binder<T, C<std::string, V, O...>>                              \
+      : public associative_binder<T, V, C<std::string, V, O...>> {             \
+  public:                                                                      \
+    using associative_binder<T, V,                                             \
+                             C<std::string, V, O...>>::associative_binder;     \
   }
 
-  ASSOCIATIVE_DIRECT_BINDER( std::map );
-//  ASSOCIATIVE_DIRECT_BINDER( std::unordered_map );
-} }
+  ASSOCIATIVE_DIRECT_BINDER(std::map);
+  //  ASSOCIATIVE_DIRECT_BINDER( std::unordered_map );
+}}

+ 31 - 29
include/json/binder/json_direct_scalar_binder.hpp

@@ -13,15 +13,14 @@
 #include <string>
 
 namespace json { namespace binder {
-  template <typename T>
-  class direct_binder<T, bool> : public binder_impl<T> {
+  template <typename T> class direct_binder<T, bool> : public binder_impl<T> {
   public:
     explicit direct_binder(bool T::*p) : ptr(p) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new direct_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options) const override {
       if (!strncmp(data, "true", 4)) {
         val.*ptr = true;
@@ -33,76 +32,79 @@ namespace json { namespace binder {
         throw json::malformed_json_exception("Expected a boolean type here");
       }
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << (val.*ptr ? "true" : "false");
     }
-    
+
   private:
     bool T::*ptr;
   };
-  
-#define JSON_IS_INTEGRAL_T(Type) \
+
+#define JSON_IS_INTEGRAL_T(Type)                                               \
   typename std::enable_if<std::is_integral<Type>::value>::type
   template <typename T, typename N>
   class direct_binder<T, N, JSON_IS_INTEGRAL_T(N)> : public binder_impl<T> {
   public:
     explicit direct_binder(N T::*p) : ptr(p) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new direct_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options) const override {
       json::helper::parse_numeric(val.*ptr, data);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << val.*ptr;
     }
+
   private:
     N T::*ptr;
   };
-  
-#define JSON_IS_FLOATING_T(Type) \
+
+#define JSON_IS_FLOATING_T(Type)                                               \
   typename std::enable_if<std::is_floating_point<Type>::value>::type
   template <typename T, typename N>
   class direct_binder<T, N, JSON_IS_FLOATING_T(N)> : public binder_impl<T> {
   public:
     explicit direct_binder(N T::*p) : ptr(p) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new direct_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options) const override {
       json::helper::parse_double(val.*ptr, data);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << std::fixed << val.*ptr;
     }
+
   private:
     N T::*ptr;
   };
-  
+
   template <typename T>
   class direct_binder<T, std::string> : public binder_impl<T> {
   public:
     explicit direct_binder(std::string T::*p) : ptr(p) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new direct_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options) const override {
       json::helper::parse_string(val.*ptr, data);
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << "\"" << json::helper::replace_all(val.*ptr, "\"", "\\\"") << "\"";
     }
+
   private:
     std::string T::*ptr;
   };
-} }
+}}

+ 25 - 22
include/json/binder/json_direct_vector_binder.hpp

@@ -10,9 +10,9 @@
 #include "json_binder.hpp"
 #include "json_direct_binder.hpp"
 
-#include <vector>
 #include <list>
 #include <set>
+#include <vector>
 
 namespace json { namespace binder {
   template <typename T, typename V, typename C>
@@ -20,16 +20,16 @@ namespace json { namespace binder {
   public:
     non_associative_binder(C T::*p) : ptr(p), impl(value_binder<V>()) {}
     non_associative_binder(C T::*p, binder<V> const & i) : ptr(p), impl(i) {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new non_associative_binder(*this);
     }
-    
-    virtual void parse(T& val, char const*& data,
+
+    virtual void parse(T & val, char const *& data,
                        parser::options opts) const override {
       const char ch = json::helper::get_next_element(data);
       if (ch != '[') { throw not_an_array_exception(val); }
       ++data;
-      
+
       V to_make;
       C & vec = val.*ptr;
       while (*data && *data != ']') {
@@ -37,11 +37,13 @@ namespace json { namespace binder {
         vec.emplace_back(to_make);
         json::helper::advance_to_boundary(']', data);
       }
-      if (*data) ++data;
-      else throw unterminated_json_array();
+      if (*data)
+        ++data;
+      else
+        throw unterminated_json_array();
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << '[';
       std::vector<V> const & vec = val.*ptr;
       auto it = vec.begin(), end = vec.end();
@@ -54,21 +56,22 @@ namespace json { namespace binder {
       }
       data << ']';
     }
+
   private:
     std::vector<V> T::*ptr;
     binder<V> impl;
   };
-  
-#define NON_ASSOCIATIVE_DIRECT_BINDER( C ) \
-  template <typename T, typename V, typename... O> \
-  class direct_binder<T, C<V, O...> > : \
-  public non_associative_binder<T, V, C<V, O...>> { \
-  public: \
-    using non_associative_binder<T, V, C<V, O...>>::non_associative_binder; \
+
+#define NON_ASSOCIATIVE_DIRECT_BINDER(C)                                       \
+  template <typename T, typename V, typename... O>                             \
+  class direct_binder<T, C<V, O...>>                                           \
+      : public non_associative_binder<T, V, C<V, O...>> {                      \
+  public:                                                                      \
+    using non_associative_binder<T, V, C<V, O...>>::non_associative_binder;    \
   }
-  
-  NON_ASSOCIATIVE_DIRECT_BINDER( std::vector );
-  NON_ASSOCIATIVE_DIRECT_BINDER( std::list );
-  NON_ASSOCIATIVE_DIRECT_BINDER( std::set );
-//  NON_ASSOCIATIVE_DIRECT_BINDER( std::unordered_set );
-} }
+
+  NON_ASSOCIATIVE_DIRECT_BINDER(std::vector);
+  NON_ASSOCIATIVE_DIRECT_BINDER(std::list);
+  NON_ASSOCIATIVE_DIRECT_BINDER(std::set);
+  //  NON_ASSOCIATIVE_DIRECT_BINDER( std::unordered_set );
+}}

+ 25 - 22
include/json/binder/json_object_binder.hpp

@@ -16,26 +16,25 @@
 #include <string>
 
 namespace json { namespace binder {
-  template <typename T>
-  class object_binder : public binder_impl<T> {
+  template <typename T> class object_binder : public binder_impl<T> {
   public:
     object_binder() {}
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new object_binder(*this);
     }
-    
+
     template <typename V>
-    object_binder& operator()(std::string const&k, V T::*ptr,
-                              binder_impl<V> const&v) {
+    object_binder & operator()(std::string const & k, V T::*ptr,
+                               binder_impl<V> const & v) {
       return (*this)(k, binder<T>(new forward_binder<T, V>(ptr, binder<V>(v))));
     }
 
-    object_binder& operator()(std::string const&k, binder<T> const&v) {
+    object_binder & operator()(std::string const & k, binder<T> const & v) {
       mapping.emplace(k, v);
       return *this;
     }
-    
-    virtual void parse(T& object, char const*& data,
+
+    virtual void parse(T & object, char const *& data,
                        parser::options opts) const override {
       const char ch = json::helper::get_next_element(data);
       if (ch == '{') {
@@ -44,8 +43,8 @@ namespace json { namespace binder {
         throw not_an_object_exception(object);
       }
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << '{';
       auto it = mapping.begin(), end = mapping.end();
       if (it != end) {
@@ -59,12 +58,14 @@ namespace json { namespace binder {
       }
       data << '}';
     }
-    
-    void parse_object(T& object, char const*& data,
+
+    void parse_object(T & object, char const *& data,
                       parser::options opts) const {
       std::string key;
       std::set<std::string> unparsed_keys;
-      for ( auto & p : mapping ) { unparsed_keys.insert(p.first); }
+      for (auto & p : mapping) {
+        unparsed_keys.insert(p.first);
+      }
       while (*data && *data != '}') {
         if (json::helper::get_next_element(data) != '"') {
           throw malformed_object_key(*data);
@@ -84,20 +85,22 @@ namespace json { namespace binder {
         }
         json::helper::advance_to_boundary('}', data);
       }
-      if (*data) ++data;
-      else throw unterminated_json_object();
-      if ( !unparsed_keys.empty() && opts & parser::disable_missing_keys ) {
+      if (*data)
+        ++data;
+      else
+        throw unterminated_json_object();
+      if (!unparsed_keys.empty() && opts & parser::disable_missing_keys) {
         throw json::malformed_json_exception{
-          "missing certain keys from object construction TODO"
-        };
+            "missing certain keys from object construction TODO"};
       }
     }
-    
+
     template <typename E>
-    object_binder& operator()(std::string const& s, E T::*p) {
+    object_binder & operator()(std::string const & s, E T::*p) {
       return operator()(s, binder<T>(new direct_binder<T, E>(p)));
     }
+
   private:
     std::map<std::string, binder<T>> mapping;
   };
-} }
+}}

+ 17 - 12
include/json/binder/json_pointer_binder.hpp

@@ -11,26 +11,31 @@
 #include "json_binder.hpp"
 
 namespace json { namespace binder {
-  template <typename P>
-  class pointer_binder : public binder_impl<P> {
+  template <typename P> class pointer_binder : public binder_impl<P> {
     // Maybe a reference type
     using Tr = decltype(*std::declval<P>());
     using T = typename std::remove_reference<Tr>::type;
+
   public:
     pointer_binder(binder<T> impl) : m_impl(impl) {}
-    
-    virtual binder_impl<P>* clone() const { return new pointer_binder(*this); }
-    
-    virtual void parse(P & v, char const*& data, parser::options opts) const {
-      if (!strncmp(data, "null", 4)) v = nullptr;
-      else m_impl.parse(*(v = P(new T)), data, opts);
+
+    virtual binder_impl<P> * clone() const { return new pointer_binder(*this); }
+
+    virtual void parse(P & v, char const *& data, parser::options opts) const {
+      if (!strncmp(data, "null", 4))
+        v = nullptr;
+      else
+        m_impl.parse(*(v = P(new T)), data, opts);
     }
-    
+
     void write(P const & v, std::ostream & os) const {
-      if (v) m_impl.write(*v, os);
-      else os << "null";
+      if (v)
+        m_impl.write(*v, os);
+      else
+        os << "null";
     }
+
   private:
     binder<T> m_impl;
   };
-} }
+}}

+ 46 - 44
include/json/binder/json_polymorphic_binder.hpp

@@ -19,53 +19,56 @@ namespace json { namespace binder {
   class polymorphic_pointer_binder : public binder_impl<PtrBase> {
   public:
     polymorphic_pointer_binder(binder<Derived> impl) : m_impl(impl) {}
-    virtual binder_impl<PtrBase>* clone() const {
+    virtual binder_impl<PtrBase> * clone() const {
       return new polymorphic_pointer_binder(*this);
     }
-    
-    virtual void parse(PtrBase & v, char const*& data,
+
+    virtual void parse(PtrBase & v, char const *& data,
                        parser::options opts) const {
-      if (!strncmp(data, "null", 4)) v = nullptr;
+      if (!strncmp(data, "null", 4))
+        v = nullptr;
       else {
         v = PtrBase(new Derived);
         Derived & actual = dynamic_cast<Derived &>(*v);
         m_impl.parse(actual, data, opts);
       }
     }
-    
+
     void write(PtrBase const & v, std::ostream & os) const {
-      if (v) m_impl.write(dynamic_cast<Derived const &>(*v), os);
-      else os << "null";
+      if (v)
+        m_impl.write(dynamic_cast<Derived const &>(*v), os);
+      else
+        os << "null";
     }
+
   private:
     binder<Derived> m_impl;
   };
-  
-  template <typename Ptr>
-  class polymorphic_binder : public binder_impl<Ptr> {
+
+  template <typename Ptr> class polymorphic_binder : public binder_impl<Ptr> {
   private:
     // Maybe a reference type
     using BaseR = decltype(*std::declval<Ptr>());
     using Base = typename std::remove_reference<BaseR>::type;
     static_assert(std::is_polymorphic<Base>::value,
                   "Must use a polymorphic type");
+
   public:
     polymorphic_binder() = default;
-    virtual binder_impl<Ptr>* clone() const override {
+    virtual binder_impl<Ptr> * clone() const override {
       return new polymorphic_binder(*this);
     }
-    
+
     template <typename Derived>
-    polymorphic_binder& operator()(std::string const&k,
-                                   binder_impl<Derived> const&v) {
+    polymorphic_binder & operator()(std::string const & k,
+                                    binder_impl<Derived> const & v) {
       mapping.emplace(k, polymorphic_pointer_binder<Ptr, Derived>(v));
-      reverse_lookup.emplace(k, [](Base const * p) {
-        return dynamic_cast<Derived const *>(p);
-      });
+      reverse_lookup.emplace(
+          k, [](Base const * p) { return dynamic_cast<Derived const *>(p); });
       return *this;
     }
-    
-    virtual void parse(Ptr & object, char const*& data,
+
+    virtual void parse(Ptr & object, char const *& data,
                        parser::options opts) const override {
       const char ch = json::helper::get_next_element(data);
       if (ch == '{') {
@@ -78,10 +81,9 @@ namespace json { namespace binder {
       data << '{';
       using pair_t = typename decltype(reverse_lookup)::value_type;
       Base const * p = std::addressof(*val);
-      auto it = std::find_if(reverse_lookup.begin(), reverse_lookup.end(),
-                             [p](pair_t const & pair) {
-                               return pair.second(p);
-                             });
+      auto it =
+          std::find_if(reverse_lookup.begin(), reverse_lookup.end(),
+                       [p](pair_t const & pair) { return pair.second(p); });
       if (it == reverse_lookup.end()) {
         throw std::domain_error("Unknown JSON binding object");
       }
@@ -90,52 +92,52 @@ namespace json { namespace binder {
       mapping.find(it->first)->second.write(val, data);
       data << '}';
     }
-    
-    void parse_object(Ptr & object, char const*& data,
+
+    void parse_object(Ptr & object, char const *& data,
                       parser::options opts) const {
       std::string key;
       fetch_expected_key("@id", data);
       if (json::helper::get_next_element(++data) != '"') {
         throw json::malformed_json_exception{
-          std::string("Expected polymorphic id starting with '\"', got '")
-          + *data + "' instead"
-        };
+            std::string("Expected polymorphic id starting with '\"', got '") +
+            *data + "' instead"};
       }
       json::helper::parse_string(key, data);
       auto it = mapping.find(key);
       if (it == mapping.end()) {
-        throw json::malformed_json_exception{
-          "Unknown polymorphic type-id: '" + key + "'"
-        };
+        throw json::malformed_json_exception{"Unknown polymorphic type-id: '" +
+                                             key + "'"};
       }
       fetch_expected_key("@value", ++data);
       it->second.parse(object, ++data, opts);
-      if (!*data) throw unterminated_json_object();
-      else if (*data != '}') throw json::malformed_json_exception{
-        std::string("Unexpected non-terminated object '") + *data + "'"
-      };
-      else ++data;
+      if (!*data)
+        throw unterminated_json_object();
+      else if (*data != '}')
+        throw json::malformed_json_exception{
+            std::string("Unexpected non-terminated object '") + *data + "'"};
+      else
+        ++data;
     }
-    
+
     void fetch_expected_key(std::string const & expected,
-                            char const*& data) const {
+                            char const *& data) const {
       std::string key;
       if (json::helper::get_next_element(data) != '"') {
         throw malformed_object_key(*data);
       }
       json::helper::parse_string(key, data);
       if (key != expected) {
-        throw json::malformed_json_exception{
-          "Expecting '" + expected + "' polymorphic token, got '"
-          + key + "' instead"
-        };
+        throw json::malformed_json_exception{"Expecting '" + expected +
+                                             "' polymorphic token, got '" +
+                                             key + "' instead"};
       }
       if (json::helper::get_next_element(data) != ':') {
         throw malformed_object_association(*data);
       }
     }
+
   private:
-    std::map<std::string, std::function<bool(Base const*)>> reverse_lookup;
+    std::map<std::string, std::function<bool(Base const *)>> reverse_lookup;
     std::map<std::string, binder<Ptr>> mapping;
   };
-} }
+}}

+ 23 - 24
include/json/binder/json_tuple_binder.hpp

@@ -13,19 +13,18 @@
 #include <vector>
 
 namespace json { namespace binder {
-  template <typename T>
-  class tuple_binder : public binder_impl<T> {
+  template <typename T> class tuple_binder : public binder_impl<T> {
   public:
-    virtual binder_impl<T>* clone() const override {
+    virtual binder_impl<T> * clone() const override {
       return new tuple_binder(*this);
     }
-    
-    tuple_binder& operator()(binder<T> const&b) {
+
+    tuple_binder & operator()(binder<T> const & b) {
       members.push_back(b);
       return *this;
     }
-    
-    virtual void parse(T& object, char const*& data,
+
+    virtual void parse(T & object, char const *& data,
                        parser::options opts) const override {
       const char ch = json::helper::get_next_element(data);
       if (ch == '[') {
@@ -34,11 +33,11 @@ namespace json { namespace binder {
         throw not_an_array_exception(object);
       }
     }
-    
-    virtual void write(T const& val, std::ostream & data) const override {
+
+    virtual void write(T const & val, std::ostream & data) const override {
       data << '[';
       typename std::vector<binder<T>>::const_iterator it = members.begin(),
-      end = members.end();
+                                                      end = members.end();
       if (it != end) {
         it->write(val, data);
         for (++it; it != end; ++it) {
@@ -48,8 +47,8 @@ namespace json { namespace binder {
       }
       data << ']';
     }
-    
-    void parse_tuple(T& object, char const*& data,
+
+    void parse_tuple(T & object, char const *& data,
                      parser::options opts) const {
       auto it = members.begin();
       while (*data && *data != ']' && it != members.end()) {
@@ -59,23 +58,23 @@ namespace json { namespace binder {
       }
       if (it != members.end()) {
         throw json::malformed_json_exception{
-          "Failed to parse every member of tuple"
-        };
+            "Failed to parse every member of tuple"};
       }
-      if (*data != ']') throw json::malformed_json_exception{
-        "Parsed every tuple element, but did not reach end"
-      };
-      else if (*data) ++data;
-      else throw unterminated_json_array();
+      if (*data != ']')
+        throw json::malformed_json_exception{
+            "Parsed every tuple element, but did not reach end"};
+      else if (*data)
+        ++data;
+      else
+        throw unterminated_json_array();
     }
-    
-    template <typename E>
-    tuple_binder& operator()(E T::*p) {
+
+    template <typename E> tuple_binder & operator()(E T::*p) {
       return operator()(binder<T>(new direct_binder<T, E>(p)));
     }
-    
+
   private:
     std::vector<binder<T>> members;
   };
 
-} }
+}}

+ 45 - 38
include/json/json.hpp

@@ -8,32 +8,31 @@
 
 #pragma once
 
-#include "variant/variant.hpp"
 #include "json_common.hpp"
+#include "variant/variant.hpp"
 
 #include <map>
-#include <vector>
 #include <utility>
+#include <vector>
 
-#define JSON_TYPE_LIST \
-  X(object) \
-  X(array) \
-  X(string) \
-  X(double) \
-  X(int) \
-  X(uint) \
+#define JSON_TYPE_LIST                                                         \
+  X(object)                                                                    \
+  X(array)                                                                     \
+  X(string)                                                                    \
+  X(double)                                                                    \
+  X(int)                                                                       \
+  X(uint)                                                                      \
   X(bool)
 
 namespace json {
   class value;
-  
-  template <>
-  void helper::parse_numeric(value & json, char const * & data);
+
+  template <> void helper::parse_numeric(value & json, char const *& data);
 
   namespace parser {
-    void parse(value&, char const*);
+    void parse(value &, char const *);
   }
-  
+
   class value {
   public:
     using object_jt = std::map<std::string, value>;
@@ -43,56 +42,64 @@ namespace json {
     using int_jt = json::int_jt;
     using uint_jt = json::uint_jt;
     using bool_jt = json::bool_jt;
+
   private:
     static const value null_value;
-    
-    using data_t = variant<object_jt, array_jt, string_jt, double_jt, int_jt, uint_jt, bool_jt>;
+
+    using data_t = variant<object_jt, array_jt, string_jt, double_jt, int_jt,
+                           uint_jt, bool_jt>;
     data_t data;
+
   public:
-#define X(type) bool is_##type() const { return data.is<type##_jt>(); }
+#define X(type)                                                                \
+  bool is_##type() const { return data.is<type##_jt>(); }
     JSON_TYPE_LIST
 #undef X
     bool is_null() const { return !data.valid(); }
-    
+
     value() = default;
-    value(value const&) = default;
+    value(value const &) = default;
     value(value &&) = default;
-    value& operator=(value const&) = default;
-    value& operator=(value &&) = default;
-#define X(type) value(type##_jt val) { data.set<type##_jt>(std::move(val)); }
+    value & operator=(value const &) = default;
+    value & operator=(value &&) = default;
+#define X(type)                                                                \
+  value(type##_jt val) { data.set<type##_jt>(std::move(val)); }
     JSON_TYPE_LIST
 #undef X
-#define X(type) value& operator=(type##_jt val) { data.set<type##_jt>(std::move(val)); return *this; }
+#define X(type)                                                                \
+  value & operator=(type##_jt val) {                                           \
+    data.set<type##_jt>(std::move(val));                                       \
+    return *this;                                                              \
+  }
     JSON_TYPE_LIST
 #undef X
-    
-    void parse(char const* data);
-    void parse(std::string const& str);
+
+    void parse(char const * data);
+    void parse(std::string const & str);
     void parse(std::istream & in);
-    
+
     void clear() { data = data_t(); }
-    
-    value& operator[](const size_t idx);
-    value const& operator[](const size_t idx) const;
-    value& operator[](std::string const& key);
-    value const& operator[](std::string const& key) const;
-    
-    string_jt const& as_string() const;
+
+    value & operator[](const size_t idx);
+    value const & operator[](const size_t idx) const;
+    value & operator[](std::string const & key);
+    value const & operator[](std::string const & key) const;
+
+    string_jt const & as_string() const;
     double_jt as_double() const;
     int_jt as_int() const;
     uint_jt as_uint() const;
     bool_jt as_bool() const;
-    
-    operator string_jt const&() const { return as_string(); }
+
+    operator string_jt const &() const { return as_string(); }
     operator double_jt() const { return as_double(); }
     operator int_jt() const { return as_int(); }
     operator uint_jt() const { return as_uint(); }
     operator bool_jt() const { return as_bool(); }
-    
   };
 #undef JSON_TYPE_LIST
   namespace parser {
     void parse(json::value &, char const *);
-    void parse(json::value& json, std::istream & in);
+    void parse(json::value & json, std::istream & in);
   }
 }

+ 3 - 3
include/json/json_binder.hpp

@@ -11,16 +11,16 @@
 #pragma once
 
 #include "binder/json_binder.hpp"
-#include "binder/json_binder_visitor.hpp"
 #include "binder/json_binder_parser.hpp"
+#include "binder/json_binder_visitor.hpp"
 #include "binder/json_direct_binder.hpp"
-#include "binder/json_tuple_binder.hpp"
-#include "binder/json_object_binder.hpp"
 #include "binder/json_direct_get_binder.hpp"
 #include "binder/json_direct_map_binder.hpp"
 #include "binder/json_direct_scalar_binder.hpp"
 #include "binder/json_direct_vector_binder.hpp"
+#include "binder/json_object_binder.hpp"
 #include "binder/json_pointer_binder.hpp"
 #include "binder/json_polymorphic_binder.hpp"
+#include "binder/json_tuple_binder.hpp"
 
 #endif /* json_binder_h */

+ 44 - 53
include/json/json_common.hpp

@@ -9,11 +9,11 @@
 
 #include <cstdint>
 #include <cstdlib>
+#include <errno.h>
 #include <limits>
 #include <stdexcept>
 #include <string>
 #include <strings.h>
-#include <errno.h>
 
 #include "json_exception.h"
 
@@ -23,16 +23,15 @@ namespace json {
   using int_jt = int32_t;
   using uint_jt = uint32_t;
   using bool_jt = bool;
-  
+
   class value;
-  
-  template <typename T = json::int_jt>
-  struct numeric_limits {
+
+  template <typename T = json::int_jt> struct numeric_limits {
     static constexpr const T max{std::numeric_limits<T>::max()};
     static constexpr const T min{std::numeric_limits<T>::min()};
-    static constexpr const uint_jt over{uint_jt{max}+1};
+    static constexpr const uint_jt over{uint_jt{max} + 1};
   };
-  
+
   namespace {
     const constexpr int_jt INT_JT_MAX = std::numeric_limits<int_jt>::max();
     const constexpr int_jt INT_JT_MAX_LAST_DIGIT = (INT_JT_MAX % 10);
@@ -45,26 +44,24 @@ namespace json {
 
 namespace json { namespace parser {
   enum options {
-    allow_all                        = 0x00,
-    disable_unknown_keys             = 0x01,
-    disable_missing_keys             = 0x02,
+    allow_all = 0x00,
+    disable_unknown_keys = 0x01,
+    disable_missing_keys = 0x02,
     disable_concatenated_json_bodies = 0x04,
-    disable_all                      = 0xFF,
+    disable_all = 0xFF,
   };
-} }
+}}
 
 namespace json { namespace helper {
-  const char get_next_element(char const*& data);
-  
-  enum numeric_state {
-    DOUBLE, INTEGER
-  };
-  
+  const char get_next_element(char const *& data);
+
+  enum numeric_state { DOUBLE, INTEGER };
+
   struct numeric_token_info {
     enum parse_state { decimal, octal, hexadecimal };
     numeric_token_info(char const * start);
     numeric_state parse_numeric();
-    
+
     uint_jt val;
     parse_state base;
     char const * it;
@@ -72,79 +69,73 @@ namespace json { namespace helper {
     bool is_double;
     bool is_negative;
   };
-  
+
   numeric_token_info get_numeric_token_info(char const * it);
-  
+
   /**
    * @throws json::malformed_json_exception
    */
   void advance_to_boundary(char const endtok, char const *& data);
-  
+
   /**
    * @throws json::malformed_json_exception
    */
-  std::string parse_string(char const * & data);
+  std::string parse_string(char const *& data);
   std::string replace_all(std::string str, std::string const & from,
                           std::string const & to);
-  
-  template <typename T>
-  void parse_string(T& json, char const * & data) {
+
+  template <typename T> void parse_string(T & json, char const *& data) {
     json::helper::get_next_element(data);
     json = parse_string(data);
   }
-  
+
   template <typename T>
-  T parse_double_impl(char const * begin, char const * & end) {
-    return std::strtod(begin, const_cast<char**>(&end));
+  T parse_double_impl(char const * begin, char const *& end) {
+    return std::strtod(begin, const_cast<char **>(&end));
   }
   template <>
-  inline float parse_double_impl<float>(char const * begin,
-                                        char const * & end) {
-    return std::strtof(begin, const_cast<char**>(&end));
+  inline float parse_double_impl<float>(char const * begin, char const *& end) {
+    return std::strtof(begin, const_cast<char **>(&end));
   }
   template <>
   inline long double parse_double_impl<long double>(char const * begin,
-                                                    char const * & end) {
-    return std::strtold(begin, const_cast<char**>(&end));
+                                                    char const *& end) {
+    return std::strtold(begin, const_cast<char **>(&end));
   }
-  
-  template <typename T>
-  void parse_double(T& json, char const * & data) {
+
+  template <typename T> void parse_double(T & json, char const *& data) {
     json::helper::get_next_element(data);
     char const * begin = data;
     errno = 0;
     T tmp = parse_double_impl<T>(begin, data);
     if (errno != 0) {
       throw json::json_numeric_width_exception{
-        "Number is out-of-range for floating-point type"
-      };
-    } else if ( begin == data ) {
+          "Number is out-of-range for floating-point type"};
+    } else if (begin == data) {
       throw json::json_numeric_exception("Expected numeric data");
     }
     errno = 0;
     json = std::move(tmp);
   }
-  
+
   template <typename J>
   bool has_too_many_digits(numeric_token_info const & info) {
-    return fls(static_cast<int_jt>(info.val))
-    > std::numeric_limits<J>::digits + info.is_negative;
+    return fls(static_cast<int_jt>(info.val)) >
+           std::numeric_limits<J>::digits + info.is_negative;
   }
-  
-  template <typename J>
-  void parse_numeric(J & json, char const * & data) {
+
+  template <typename J> void parse_numeric(J & json, char const *& data) {
     json::helper::get_next_element(data);
     numeric_token_info info = data;
-    if ( info.is_negative && !std::is_signed<J>::value ) {
+    if (info.is_negative && !std::is_signed<J>::value) {
       throw json_numeric_exception("Expected signed integer");
-    } else if ( info.is_double || info.parse_numeric() == DOUBLE ) {
+    } else if (info.is_double || info.parse_numeric() == DOUBLE) {
       throw json_numeric_exception("Expected integer, got double");
     } else if (info.base == numeric_token_info::decimal &&
-               (has_too_many_digits<J>(info)
-               || info.val > json::numeric_limits<J>::over)) {
+               (has_too_many_digits<J>(info) ||
+                info.val > json::numeric_limits<J>::over)) {
       throw json_numeric_width_exception{
-        "Integer width too small for parsed value"
-      };
+          "Integer width too small for parsed value"};
     } else if (info.is_negative) {
       if (info.val == json::numeric_limits<J>::over) {
         json = json::numeric_limits<J>::min;
@@ -161,4 +152,4 @@ namespace json { namespace helper {
     }
     data = info.it;
   }
-} }
+}}

+ 16 - 25
include/json/json_exception.h

@@ -12,61 +12,52 @@
 #include <typeinfo>
 
 namespace json {
-  class malformed_json_exception :
-  public std::domain_error {
+  class malformed_json_exception : public std::domain_error {
     using std::domain_error::domain_error;
   };
-  
-  struct not_an_object_exception :
-  public malformed_json_exception {
+
+  struct not_an_object_exception : public malformed_json_exception {
     template <typename T>
     not_an_object_exception(T const &)
-    : not_an_object_exception(typeid(T).name()) {}
+        : not_an_object_exception(typeid(T).name()) {}
     not_an_object_exception(char const * tname);
   };
 
-  class not_an_array_exception :
-  public malformed_json_exception {
+  class not_an_array_exception : public malformed_json_exception {
   public:
     template <typename T>
     not_an_array_exception(T const &)
-    : not_an_array_exception(typeid(T).name()) {}
+        : not_an_array_exception(typeid(T).name()) {}
+
   private:
     not_an_array_exception(char const * tname);
   };
 
-  struct malformed_object_key :
-  public malformed_json_exception {
+  struct malformed_object_key : public malformed_json_exception {
     malformed_object_key(char instead);
   };
 
-  struct malformed_object_association :
-  public malformed_json_exception {
+  struct malformed_object_association : public malformed_json_exception {
     malformed_object_association(char instead);
   };
 
-  class unterminated_json_exception :
-  public malformed_json_exception {
+  class unterminated_json_exception : public malformed_json_exception {
     using malformed_json_exception::malformed_json_exception;
   };
-  
-  struct unterminated_json_array :
-  public unterminated_json_exception {
+
+  struct unterminated_json_array : public unterminated_json_exception {
     unterminated_json_array();
   };
 
-  struct unterminated_json_object :
-  public unterminated_json_exception {
+  struct unterminated_json_object : public unterminated_json_exception {
     unterminated_json_object();
   };
 
-  class json_numeric_exception :
-  public std::domain_error {
+  class json_numeric_exception : public std::domain_error {
     using std::domain_error::domain_error;
   };
-  
-  class json_numeric_width_exception :
-  public json_numeric_exception {
+
+  class json_numeric_width_exception : public json_numeric_exception {
     using json_numeric_exception::json_numeric_exception;
   };
 }

+ 16 - 18
src/json.cpp

@@ -11,9 +11,9 @@
 const json::value json::value::null_value{};
 
 template <>
-void json::helper::parse_numeric(json::value & json, char const * & data) {
+void json::helper::parse_numeric(json::value & json, char const *& data) {
   numeric_token_info info = data;
-  if ( info.is_double || info.parse_numeric() == DOUBLE ) {
+  if (info.is_double || info.parse_numeric() == DOUBLE) {
     helper::parse_double(json, data);
   } else {
     uint_jt const val = info.val;
@@ -32,32 +32,30 @@ void json::helper::parse_numeric(json::value & json, char const * & data) {
   }
 }
 
-json::value& json::value::operator[](const size_t idx) {
-  if (!is_array()) {
-    data.set<array_jt>();
-  }
+json::value & json::value::operator[](const size_t idx) {
+  if (!is_array()) { data.set<array_jt>(); }
   array_jt & val = data.get<array_jt>();
-  if (val.size() <= idx) val.resize(idx+1);
+  if (val.size() <= idx) val.resize(idx + 1);
   return val[idx];
 }
 
-json::value const& json::value::operator[](const size_t idx) const {
+json::value const & json::value::operator[](const size_t idx) const {
   if (!is_array()) return null_value;
-  array_jt const& val = data.get<array_jt>();
-  if (val.size() <= idx) return null_value;
-  else return val[idx];
+  array_jt const & val = data.get<array_jt>();
+  if (val.size() <= idx)
+    return null_value;
+  else
+    return val[idx];
 }
 
-json::value& json::value::operator[](std::string const& key) {
-  if (!is_object()) {
-    data.set<object_jt>();
-  }
+json::value & json::value::operator[](std::string const & key) {
+  if (!is_object()) { data.set<object_jt>(); }
   return data.get<object_jt>()[key];
 }
 
-json::value const& json::value::operator[](std::string const& key) const {
+json::value const & json::value::operator[](std::string const & key) const {
   if (!is_object()) return null_value;
-  object_jt const& val = data.get<object_jt>();
+  object_jt const & val = data.get<object_jt>();
   auto it = val.find(key);
   if (it != val.end()) {
     return it->second;
@@ -66,7 +64,7 @@ json::value const& json::value::operator[](std::string const& key) const {
   }
 }
 
-json::value::string_jt const& json::value::as_string() const {
+json::value::string_jt const & json::value::as_string() const {
   return data.get<string_jt>();
 }
 

+ 35 - 28
src/json_binder_discard.cpp

@@ -13,24 +13,25 @@
 
 namespace json { namespace {
   struct discard_t {
-    template <typename T> discard_t & operator= (T const &) { return *this; }
+    template <typename T> discard_t & operator=(T const &) { return *this; }
     template <typename T> discard_t & operator[](T const &) { return *this; }
   };
-} }
+}}
 
 namespace json { namespace helper {
   template <>
-  void parse_numeric<json::discard_t>(json::discard_t &, char const * & data);
+  void parse_numeric<json::discard_t>(json::discard_t &, char const *& data);
   template <>
-  json::discard_t parse_double_impl<json::discard_t>(const char *begin, const char *&end);
-} }
+  json::discard_t parse_double_impl<json::discard_t>(const char * begin,
+                                                     const char *& end);
+}}
 
 namespace json { namespace {
-  void parse_object(discard_t& json, char const*& data);
-  void parse_array(discard_t& json, char const*& data);
-  void parse_one_token(discard_t& json, char const*& data);
-  
-  void parse_one_token(discard_t& json, char const*& data) {
+  void parse_object(discard_t & json, char const *& data);
+  void parse_array(discard_t & json, char const *& data);
+  void parse_one_token(discard_t & json, char const *& data);
+
+  void parse_one_token(discard_t & json, char const *& data) {
     const char ch = helper::get_next_element(data);
     if (ch == '{') {
       parse_object(json, ++data);
@@ -48,54 +49,60 @@ namespace json { namespace {
       helper::parse_numeric(json, data);
     }
   }
-  
-  void parse_object(discard_t& json, char const*& data) {
+
+  void parse_object(discard_t & json, char const *& data) {
     std::string key;
     while (*data && *data != '}') {
       helper::parse_string(key, data);
       if (helper::get_next_element(data) != ':') {
-        throw malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
+        throw malformed_object_association(*data);
       }
       parse_one_token(json[key], ++data);
       helper::advance_to_boundary('}', data);
     }
-    if (*data) ++data;
-    else throw malformed_json_exception("Reached end of parse string without finding object end");
+    if (*data) {
+      ++data;
+    } else {
+      throw unterminated_json_object();
+    }
   }
-  
-  void parse_array(discard_t& json, char const*& data) {
+
+  void parse_array(discard_t & json, char const *& data) {
     size_t current_idx = 0;
     while (*data && *data != ']') {
       parse_one_token(json[current_idx++], data);
       helper::advance_to_boundary(']', data);
     }
-    if (*data) ++data;
-    else throw malformed_json_exception("Reached end of parse string without finding array end");
+    if (*data) {
+      ++data;
+    } else {
+      throw unterminated_json_array();
+    }
   }
-} }
+}}
 
 namespace json { namespace helper {
   template <>
-  discard_t parse_double_impl<discard_t>(const char *begin, const char *&end) {
+  discard_t parse_double_impl<discard_t>(const char * begin,
+                                         const char *& end) {
     std::strtod(begin, const_cast<char **>(&end));
     errno = 0;
     return {};
   }
-  
-  template <>
-  void parse_numeric<discard_t>(discard_t & d, char const * & data) {
+
+  template <> void parse_numeric<discard_t>(discard_t & d, char const *& data) {
     numeric_token_info info = data;
-    if ( info.is_double || info.parse_numeric() == DOUBLE ) {
+    if (info.is_double || info.parse_numeric() == DOUBLE) {
       helper::parse_double(d, data);
     } else {
       data = info.it;
     }
   }
-} }
+}}
 
 namespace json {
-  void parse_discard_token( char const * & data ) {
+  void parse_discard_token(char const *& data) {
     json::discard_t tmp;
-    parse_one_token( tmp, data );
+    parse_one_token(tmp, data);
   }
 }

+ 53 - 62
src/json_common.cpp

@@ -13,56 +13,47 @@
 namespace json { namespace helper {
   namespace {
     std::string get_no_end_error(char expected, char found) {
-      char str[64] = { '\0' };
+      char str[64] = {'\0'};
       snprintf(str, sizeof(str),
-               "Expected delimeter: ',' or '%c', got '%c' instead",
-               expected, found);
+               "Expected delimeter: ',' or '%c', got '%c' instead", expected,
+               found);
       return str;
     }
   }
-  
+
   namespace {
     std::map<numeric_token_info::parse_state, uint_jt> bases{
-      { numeric_token_info::decimal,     10 },
-      { numeric_token_info::octal,        8 },
-      { numeric_token_info::hexadecimal, 16 }
-    };
+        {numeric_token_info::decimal, 10},
+        {numeric_token_info::octal, 8},
+        {numeric_token_info::hexadecimal, 16}};
     std::map<numeric_token_info::parse_state, std::string> allowed{
-      { numeric_token_info::decimal,     "0123456789" },
-      { numeric_token_info::octal,       "01234567" },
-      { numeric_token_info::hexadecimal, "0123456789aAbBcCdDeEfF" }
-    };
+        {numeric_token_info::decimal, "0123456789"},
+        {numeric_token_info::octal, "01234567"},
+        {numeric_token_info::hexadecimal, "0123456789aAbBcCdDeEfF"}};
     std::map<char, uint_jt> values{
-      { '0',  0 }, { '1',  1 }, { '2',  2 }, { '3',  3 },
-      { '4',  4 }, { '5',  5 }, { '6',  6 }, { '7',  7 },
-      { '8',  8 }, { '9',  9 }, { 'a', 10 }, { 'A', 10 },
-      { 'b', 11 }, { 'B', 11 }, { 'c', 12 }, { 'C', 12 },
-      { 'd', 13 }, { 'D', 13 }, { 'e', 14 }, { 'E', 14 },
-      { 'f', 15 }, { 'F', 15 }
-    };
+        {'0', 0},  {'1', 1},  {'2', 2},  {'3', 3},  {'4', 4},  {'5', 5},
+        {'6', 6},  {'7', 7},  {'8', 8},  {'9', 9},  {'a', 10}, {'A', 10},
+        {'b', 11}, {'B', 11}, {'c', 12}, {'C', 12}, {'d', 13}, {'D', 13},
+        {'e', 14}, {'E', 14}, {'f', 15}, {'F', 15}};
     std::map<numeric_token_info::parse_state, uint_jt> thresholds{
-      { numeric_token_info::decimal,     UINT_JT_MAX / 10 },
-      { numeric_token_info::octal,       UINT_JT_MAX /  8 },
-      { numeric_token_info::hexadecimal, UINT_JT_MAX / 16 }
-    };
+        {numeric_token_info::decimal, UINT_JT_MAX / 10},
+        {numeric_token_info::octal, UINT_JT_MAX / 8},
+        {numeric_token_info::hexadecimal, UINT_JT_MAX / 16}};
     std::map<numeric_token_info::parse_state, uint_jt> last_digits{
-      { numeric_token_info::decimal,     INT_JT_MAX % 10 },
-      { numeric_token_info::octal,       INT_JT_MAX %  8 },
-      { numeric_token_info::hexadecimal, INT_JT_MAX % 16 }
-    };
-    
+        {numeric_token_info::decimal, INT_JT_MAX % 10},
+        {numeric_token_info::octal, INT_JT_MAX % 8},
+        {numeric_token_info::hexadecimal, INT_JT_MAX % 16}};
   }
-  
+
   // TODO - parse hex and octal
   numeric_token_info::numeric_token_info(char const * start)
-  : val(0)
-  , base(decimal)
-  , it(start)
-  , end(start)
-  , is_double(false)
-  , is_negative(*start == '-') {
-    if ( is_negative ) { ++it; ++end; }
-    if ( *end == '0' ) {
+      : val(0), base(decimal), it(start), end(start), is_double(false),
+        is_negative(*start == '-') {
+    if (is_negative) {
+      ++it;
+      ++end;
+    }
+    if (*end == '0') {
       base = octal;
       ++end;
       if (strchr("xX", *end)) {
@@ -70,20 +61,19 @@ namespace json { namespace helper {
         ++end;
       }
     }
-    for (char c = *end;
-         !strchr(",]}", c) && !isspace(c);
-         c = *++end) {
+    for (char c = *end; !strchr(",]}", c) && !isspace(c); c = *++end) {
       is_double |= !strchr(allowed[base].c_str(), c);
     }
-    
-    if ( is_negative && base != decimal ) {
-      throw json_numeric_exception("Only decimal numbers can be recorded as negative");
+
+    if (is_negative && base != decimal) {
+      throw json_numeric_exception(
+          "Only decimal numbers can be recorded as negative");
     }
     if (end == it) {
       throw unterminated_json_exception("Expected any token, got nothing");
     }
   }
-  
+
   numeric_state numeric_token_info::parse_numeric() {
     uint_jt const threshold = thresholds[base];
     uint_jt const last_digit = last_digits[base];
@@ -91,22 +81,21 @@ namespace json { namespace helper {
     for (char c = *it; it != end; c = *++it) {
       uint_jt digit = values[c];
       if (val > threshold ||
-          ( val == threshold && ((it + 1) < end ||
-                                 digit > last_digit))) {
+          (val == threshold && ((it + 1) < end || digit > last_digit))) {
         return DOUBLE;
       }
       val = (bases[base] * val) + digit;
     }
     return INTEGER;
   }
-  
-  
-  const char get_next_element(char const*& data) {
-    while (isspace(*data)) ++data;
+
+  const char get_next_element(char const *& data) {
+    while (isspace(*data))
+      ++data;
     return *data;
   }
-  
-  void advance_to_boundary(char const endtok, char const*& data) {
+
+  void advance_to_boundary(char const endtok, char const *& data) {
     char const next = get_next_element(data);
     if (next == ',') {
       ++data;
@@ -114,30 +103,32 @@ namespace json { namespace helper {
       throw unterminated_json_exception(get_no_end_error(endtok, *data));
     }
   }
-  
+
   int reverse_count(char const * data, char val) {
     int i = 0;
-    while (*data-- == val) { ++i; }
+    while (*data-- == val) {
+      ++i;
+    }
     return i;
   }
-  
+
   std::string replace_all(std::string str, std::string const & from,
                           std::string const & to) {
     std::string::size_type start_pos = 0;
-    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
+    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
       str.replace(start_pos, from.length(), to);
       start_pos += to.length(); // ...
     }
     return str;
   }
-  
-  std::string parse_string(char const * & data) {
-    char const* start = data;
+
+  std::string parse_string(char const *& data) {
+    char const * start = data;
     while (*++data) {
-      if (*data == '"' && (reverse_count(data-1, '\\') % 2) == 0) {
-        return replace_all(std::string(start+1, data++), "\\\"", "\"");
+      if (*data == '"' && (reverse_count(data - 1, '\\') % 2) == 0) {
+        return replace_all(std::string(start + 1, data++), "\\\"", "\"");
       }
     }
     throw unterminated_json_exception("Could not locate end of string");
   }
-} }
+}}

+ 16 - 24
src/json_exception.cxx

@@ -14,43 +14,35 @@ using namespace json;
 
 namespace {
   const std::string uterm_array_msg{
-    "Reached end of parse string without finding array end"
-  };
+      "Reached end of parse string without finding array end"};
   const std::string uterm_object_msg{
-    "Reached end of parse string without finding object end"
-  };
-  
+      "Reached end of parse string without finding object end"};
+
   const std::string object_assoc_msg{
-    "Expected key:value pair delimited by ':', got '"
-  };
-  
+      "Expected key:value pair delimited by ':', got '"};
+
   const std::string object_key_msg{
-    "Expected object key starting with '\"', got '"
-  };
-  
-  const std::string not_object_msg{
-    "Expected an object type for binding to "
-  };
-
-  const std::string not_array_msg{
-    "Expected an array type for binding to "
-  };
+      "Expected object key starting with '\"', got '"};
+
+  const std::string not_object_msg{"Expected an object type for binding to "};
+
+  const std::string not_array_msg{"Expected an array type for binding to "};
 }
 
 not_an_object_exception::not_an_object_exception(char const * tname)
-: malformed_json_exception(not_object_msg + tname) {}
+    : malformed_json_exception(not_object_msg + tname) {}
 
 not_an_array_exception::not_an_array_exception(char const * tname)
-: malformed_json_exception(not_array_msg + tname) {}
+    : malformed_json_exception(not_array_msg + tname) {}
 
 malformed_object_key::malformed_object_key(char instead)
-: malformed_json_exception(object_key_msg + instead + "' instead") {}
+    : malformed_json_exception(object_key_msg + instead + "' instead") {}
 
 malformed_object_association::malformed_object_association(char instead)
-: malformed_json_exception(object_assoc_msg + instead + "' instead") {}
+    : malformed_json_exception(object_assoc_msg + instead + "' instead") {}
 
 unterminated_json_array::unterminated_json_array()
-: unterminated_json_exception(uterm_array_msg) {}
+    : unterminated_json_exception(uterm_array_msg) {}
 
 unterminated_json_object::unterminated_json_object()
-: unterminated_json_exception(uterm_array_msg) {}
+    : unterminated_json_exception(uterm_array_msg) {}

+ 38 - 37
src/json_parser.cpp

@@ -11,11 +11,11 @@
 #include "json/json_common.hpp"
 
 namespace json { namespace {
-  void parse_object(value& json, char const*& data);
-  void parse_array(value& json, char const*& data);
-  void parse_one_token(value& json, char const*& data);
-  
-  void parse_one_token(value& json, char const*& data) {
+  void parse_object(value & json, char const *& data);
+  void parse_array(value & json, char const *& data);
+  void parse_one_token(value & json, char const *& data);
+
+  void parse_one_token(value & json, char const *& data) {
     const char ch = helper::get_next_element(data);
     if (ch == '{') {
       parse_object(json, ++data);
@@ -31,58 +31,59 @@ namespace json { namespace {
       helper::parse_numeric(json, data);
     }
   }
-      
-  void parse_object(value& json, char const*& data) {
+
+  void parse_object(value & json, char const *& data) {
     std::string key;
     while (*data && *data != '}') {
       helper::parse_string(key, data);
       if (helper::get_next_element(data) != ':') {
-        throw malformed_json_exception(std::string("Expected key:value pair delimited by ':', got '") + *data + "' instead");
+        throw malformed_object_association(*data);
       }
       parse_one_token(json[key], ++data);
       helper::advance_to_boundary('}', data);
     }
-    if (*data) ++data;
-    else throw malformed_json_exception("Reached end of parse string without finding object end");
+    if (*data)
+      ++data;
+    else
+      throw unterminated_json_object();
   }
-  
-  void parse_array(value& json, char const*& data) {
+
+  void parse_array(value & json, char const *& data) {
     size_t current_idx = 0;
     while (*data && *data != ']') {
       parse_one_token(json[current_idx++], data);
       helper::advance_to_boundary(']', data);
     }
-    if (*data) ++data;
-    else throw malformed_json_exception("Reached end of parse string without finding array end");
+    if (*data)
+      ++data;
+    else
+      throw unterminated_json_array();
   }
-} }
+}}
 
-namespace json {
-  namespace parser {
-    void parse(json::value& json, char const* data) {
-      parse_one_token(json, data);
-      if (*data) throw malformed_json_exception("Expected a single json token in top-level parse");
-    }
-    
-    void parse(json::value& json, std::istream & in) {
-      in.seekg(0, std::ios_base::end);
-      std::istream::pos_type end = in.tellg();
-      std::unique_ptr<char[]> data{new char[end]};
-      in.seekg(0);
-      in.read(data.get(), end);
-      parse(json, data.get());
+namespace json { namespace parser {
+  void parse(json::value & json, char const * data) {
+    parse_one_token(json, data);
+    if (*data) {
+      throw malformed_json_exception{
+          "Expected a single json token in top-level parse"};
     }
   }
-}
 
-void json::value::parse(char const* data) {
-  json::parser::parse(*this, data);
-}
+  void parse(json::value & json, std::istream & in) {
+    in.seekg(0, std::ios_base::end);
+    std::istream::pos_type end = in.tellg();
+    std::unique_ptr<char[]> data{new char[end]};
+    in.seekg(0);
+    in.read(data.get(), end);
+    parse(json, data.get());
+  }
+}}
 
-void json::value::parse(std::string const& str) {
+void json::value::parse(char const * data) { json::parser::parse(*this, data); }
+
+void json::value::parse(std::string const & str) {
   json::parser::parse(*this, str.c_str());
 }
 
-void json::value::parse(std::istream & in) {
-  json::parser::parse(*this, in);
-}
+void json::value::parse(std::istream & in) { json::parser::parse(*this, in); }