GCC Code Coverage Report


Directory: ./
File: ecapp/Capability.h
Date: 2026-09-03 16:05:57
Exec Total Coverage
Lines: 4 5 80.0%
Branches: 4 20 20.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * This file is part of the ecapp library (EtherCAT application devices).
4 *
5 * Copyright (C) 2026 Florian Pose <fp@igh.de>
6 *
7 * The ecapp library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, version 3 of the
10 * License.
11 *
12 * The ecapp library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with the ecapp library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #ifndef ECAPP_CAPABILITY_H
24 #define ECAPP_CAPABILITY_H
25
26 /****************************************************************************/
27
28 #include "ecapp/Exceptions.h"
29 #include "ecapp/SubDevice.h"
30
31 #include <string>
32 #include <typeinfo>
33
34 /****************************************************************************/
35
36 namespace EcApp {
37
38 /** Optional, not-every-device abilities (e.g. IAnalogInputRange) are
39 * modeled as small interfaces that a concrete device class multiply
40 * inherits from, instead of virtuals-with-default-throw on SubDevice
41 * itself -- that would force every new device family to grow the base
42 * interface. capability<T>() is the runtime-checked dynamic_cast to one
43 * of those interfaces. */
44 template <typename Capability>
45 8 Capability &capability(SubDevice &device)
46 {
47
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
8 auto *cap = dynamic_cast<Capability *>(&device);
48
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
8 if (!cap) {
49 throw UnsupportedCapability(
50 std::string("Device does not implement capability ")
51 + typeid(Capability).name());
52 }
53 8 return *cap;
54 }
55
56 template <typename Capability>
57 bool hasCapability(const SubDevice &device)
58 {
59 return dynamic_cast<const Capability *>(&device) != nullptr;
60 }
61
62 } // namespace EcApp
63
64 #endif // ECAPP_CAPABILITY_H
65
66 /****************************************************************************/
67