STIR  6.2.0
ByteOrder.h
Go to the documentation of this file.
1 #ifndef __stir_ByteOrder_H__
2 #define __stir_ByteOrder_H__
3 
13 /*
14  Copyright (C) 2000 PARAPET partners
15  Copyright (C) 2000-2009 Hammersmith Imanet Ltd
16  This file is part of STIR.
17 
18  SPDX-License-Identifier: Apache-2.0 AND License-ref-PARAPET-license
19 
20  See STIR/LICENSE.txt for details
21 */
22 /*
23  Modification History:
24 
25  - First version by KT
26 
27  - AZ&KT 15/12/99 rewrote swap_order using revert_region
28 */
29 
30 #include "stir/common.h"
31 // for swap
32 #include <algorithm>
33 
34 START_NAMESPACE_STIR
35 
52 /*
53  \brief Internal class to swap bytes.
54 
55  This defines a revert function that swaps the outer elements of an
56  array, and then calls itself recursively.
57  Due to the use of templates, the recursion gets resolved at compile
58  time.
59  (We have to use a class for this, as we rely on
60  template specialisation, which is unavailable for functions).
61 
62  \warning This class should not be used anywhere, except in the
63  ByteOrder::swap_order implementation.
64 
65  \internal
66 */
67 /*
68  It really shouldn't be in this include file, but we have to because
69  of a compiler bug in VC++ (member templates have to be defined in the
70  class).
71 */
72 // TODO put revert_region in own namespace or as private class of ByteOrder
73 
74 template <int size>
75 class revert_region
76 {
77 public:
78  inline static void revert(unsigned char* ptr)
79  {
80  std::swap(ptr[0], ptr[size - 1]);
81  revert_region<size - 2>::revert(ptr + 1);
82  }
83 };
84 
85 template <>
86 class revert_region<1>
87 {
88 public:
89  inline static void revert(unsigned char* ptr) {}
90 };
91 
92 template <>
93 class revert_region<0>
94 {
95 public:
96  inline static void revert(unsigned char* ptr) {}
97 };
98 
99 class ByteOrder
100 {
101 public:
103  enum Order
104  {
108  swapped
109  };
110 
111  //******* static members (i.e. not using 'this')
112 
114  inline static Order get_native_order();
115 
116  // Note: this uses member templates. If your compiler cannot handle it,
117  // you will have to write lots of lines for the built-in types
118  // Note: Implementation has to be inside the class definition to get
119  // this compiled by VC++ 5.0 and 6.0
121  template <class NUMBER>
122  inline static void swap_order(NUMBER& value)
123  {
124  revert_region<sizeof(NUMBER)>::revert(reinterpret_cast<unsigned char*>(&value));
125  }
126 
127  //********* non-static members
128 
130  inline ByteOrder(Order byte_order = native);
131 
133  inline bool operator==(const ByteOrder order2) const;
134  inline bool operator!=(const ByteOrder order2) const;
135 
137  inline bool is_native_order() const;
138 
139  // Note: this uses member templates. If your compiler cannot handle it,
140  // you will have to write lots of lines for the built-in types
141  // Note: Implementation has to be inside the class definition to get
142  // this compiled by VC++ 5.0 and 6.0
144  template <class NUMBER>
145  inline void swap_if_necessary(NUMBER& a) const
146  {
147  if (!is_native_order())
148  swap_order(a);
149  }
150 
151 private:
152  // This static member has to be initialised somewhere (in file scope).
153  static const Order native_order;
154 
155  Order byte_order;
156 };
157 
158 END_NAMESPACE_STIR
159 
160 #include "stir/ByteOrder.inl"
161 
162 #endif
static void swap_order(NUMBER &value)
swap the byteorder of the argument
Definition: ByteOrder.h:122
Order
enum for specifying the byte-order
Definition: ByteOrder.h:103
Definition: ByteOrder.h:106
This class provides member functions to find out what byte-order your machine is and to swap numbers...
Definition: ByteOrder.h:99
void swap_if_necessary(NUMBER &a) const
this swaps only when the order != native order
Definition: ByteOrder.h:145
This file declares the stir::ByteOrder class.
Definition: ByteOrder.h:105
basic configuration include file
Definition: ByteOrder.h:107