JSON Voorhees
Killer JSON for C++
Loading...
Searching...
No Matches
extractor_construction.hpp
Go to the documentation of this file.
1/// \file jsonv/serialization/extractor_construction.hpp
2///
3/// Copyright (c) 2015-2026 by Travis Gockel. All rights reserved.
4///
5/// This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
6/// as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
7/// version.
8///
9/// \author Travis Gockel (travis@gockelhut.com)
10#pragma once
11
12#include <jsonv/config.hpp>
14
15#include <concepts>
16#include <expected>
17#include <new>
18
19namespace jsonv
20{
21
22/// \addtogroup Serialization
23/// \{
24
25/// An \c extractor for a type \c T with an extracting constructor.
26///
27/// Four constructor shapes are accepted, preferred in this order: <tt>T(reader&, extraction_context&)</tt>,
28/// <tt>T(reader&)</tt>, <tt>T(const value&, extraction_context&)</tt> and <tt>T(const value&)</tt>. The last two
29/// are the shapes which predate extraction running off a \c reader; they are handed a subtree materialised by
30/// \c read_value, so they keep working but pay for the tree they were always paying for.
31template <typename T>
33 public extractor
34{
35public:
36 /// \see extractor::get_type
38 virtual const std::type_info& get_type() const noexcept override
39 {
40 return typeid(T);
41 }
42
43 /// \see extractor::extract
45 virtual std::expected<void, ast_node_type>
46 extract(extraction_context& context, reader& from, void* into) const override
47 {
48 if constexpr (std::constructible_from<T, reader&, extraction_context&>)
49 {
50 new(into) T(from, context);
51 }
52 else if constexpr (std::constructible_from<T, reader&>)
53 {
54 new(into) T(from);
55 }
56 else if constexpr (std::constructible_from<T, const value&, extraction_context&>)
57 {
58 detail::borrowed_subtree subtree(context, from);
59 new(into) T(subtree.get(), context);
60 subtree.commit();
61 }
62 else
63 {
64 static_assert(std::constructible_from<T, const value&>,
65 "extractor_construction<T> requires T to be constructible from (reader&, "
66 "extraction_context&), (reader&), (const value&, extraction_context&) or (const value&)"
67 );
68
69 detail::borrowed_subtree subtree(context, from);
70 new(into) T(subtree.get());
71 subtree.commit();
72 }
73
74 // A constructor which fails does so by throwing, and a throwing placement-new constructs nothing, so there is
75 // never a half-built object in `into` to clean up here. extraction_context::extract turns the exception into a
76 // problem on the context.
77 return {};
78 }
79};
80
81/// \}
82
83}
Provides extra information to routines used for extraction and serialization.
Definition context.hpp:26
Provides extra information to routines used for extraction, collects the problems they encounter,...
Definition extract.hpp:391
An extractor for a type T with an extracting constructor.
virtual const std::type_info & get_type() const noexcept override
virtual std::expected< void, ast_node_type > extract(extraction_context &context, reader &from, void *into) const override
An extractor holds the method for converting JSON source into an arbitrary C++ type.
Definition extract.hpp:345
A reader instance reads from some form of JSON source (probably a string) and converts it into a JSON...
Definition reader.hpp:104
Copyright (c) 2014-2020 by Travis Gockel.
Extraction of C++ types from a JSON AST.
#define JSONV_NODISCARD
Warn if the caller discards the result of this function.
Definition config.hpp:132