PLYwoot
Header-only C++17 library for parsing and writing PLY files
Loading...
Searching...
No Matches
parser_variant.hpp
Go to the documentation of this file.
1/*
2 This file is part of PLYwoot, a header-only PLY parser.
3
4 Copyright (C) 2023-2025, Ton van den Heuvel
5
6 PLYwoot is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef PLYWOOT_PARSER_VARIANT_HPP
21#define PLYWOOT_PARSER_VARIANT_HPP
22
24
27#include "parser.hpp"
28
29#include <istream>
30#include <variant>
31
32namespace plywoot::detail {
33
35class ParserVariant
36{
37public:
38 ParserVariant(std::istream &is, PlyFormat format) : variant_{makeVariant(is, format)} {}
39
40 PlyElementData read(const PlyElement &element) const
41 {
42 return std::visit([&](auto &&parser) { return parser.read(element); }, variant_);
43 }
44
45 template<typename Layout>
46 void read(const PlyElement &element, std::uint8_t *dest, std::size_t alignment) const
47 {
48 VisitHelper<Layout>::visit(element, dest, alignment, variant_);
49 }
50
51 void skip(const PlyElement &element) const
52 {
53 std::visit([&element](auto &&parser) { parser.skip(element); }, variant_);
54 }
55
56private:
57 using Variant = std::variant<
58 detail::Parser<detail::AsciiParserPolicy>,
59 detail::Parser<detail::BinaryBigEndianParserPolicy>,
60 detail::Parser<detail::BinaryLittleEndianParserPolicy>>;
61
62 // Note; VisitHelper exists to be able to extract `Ts...` from `Layout`.
63 template<typename Layout>
64 struct VisitHelper;
65
66 template<template <typename ...> class Layout, typename ...Ts>
67 struct VisitHelper<Layout<Ts...>>
68 {
69 static void visit(const PlyElement &element, std::uint8_t *dest, std::size_t alignment, const Variant &v)
70 {
71 std::visit([&element, dest, alignment](auto &&parser) { parser.template read<Ts...>(element, dest, alignment); }, v);
72 }
73 };
74
75 Variant makeVariant(std::istream &is, PlyFormat format)
76 {
77 switch (format)
78 {
79 case PlyFormat::Ascii:
80 return Variant{std::in_place_type<detail::Parser<detail::AsciiParserPolicy>>, is};
81 case PlyFormat::BinaryBigEndian:
82 return Variant{std::in_place_type<detail::Parser<detail::BinaryBigEndianParserPolicy>>, is};
83 case PlyFormat::BinaryLittleEndian:
84 default:
85 break;
86 }
87
88 return Variant{std::in_place_type<detail::Parser<detail::BinaryLittleEndianParserPolicy>>, is};
89 }
90
91 Variant variant_;
92};
93
94}
95
96#endif