libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
isin_impl.hpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2016 by J.M.McGuiness, isimud@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 namespace isimud { namespace ISIMUD_VER_NAMESPACE { namespace exchanges { namespace common {
20 
21 constexpr inline
22 ISIN_t::ISIN_t() noexcept(true)
23 : value{} {
24 }
25 
26 constexpr inline
27 ISIN_t::ISIN_t(block_t const &b) noexcept(true) {
28  libjmmcg::memcpy_opt(b, value.block);
29 }
30 
31 constexpr inline
32 ISIN_t::ISIN_t(ISIN_t const &i) noexcept(true) {
33  libjmmcg::memcpy_opt(i.value.block, value.block);
34 }
35 
36 template<std::size_t Sz>
37 constexpr inline
38 ISIN_t::ISIN_t(block_t::value_type const (&b)[Sz]) noexcept(true) {
39  BOOST_MPL_ASSERT_RELATION(sizeof(block_t), ==, Sz-1);
40  libjmmcg::memcpy_opt(reinterpret_cast<block_t const &>(b), value.block);
41 }
42 
43 constexpr inline ISIN_t&
44 ISIN_t::operator=(ISIN_t const &i) noexcept(true) {
45  libjmmcg::memcpy_opt(i.value.block, value.block);
46  return *this;
47 }
48 
49 inline bool
50 ISIN_t::operator==(ISIN_t const &i) const noexcept(true) {
51  return value.block==i.value.block;
52 }
53 
54 inline bool
55 ISIN_t::operator<(ISIN_t const &i) const noexcept(true) {
56  static_assert(sizeof(ISIN_t)<=sizeof(libjmmcg::uint128_t));
57  union converter {
58  static_assert(sizeof(libjmmcg::uint128_t)>=sizeof(ISIN_t));
59  enum : std::size_t {
60  conv_sz=sizeof(libjmmcg::uint128_t),
61  isin_sz=sizeof(ISIN_t),
62  num_chars_to_mask=(conv_sz-isin_sz)*8
63  };
64 
65  libjmmcg::uint128_t conv;
66  ISIN_t isin;
67 
68  explicit constexpr converter(ISIN_t const &i) noexcept(true)
69  : isin(i) {
70  }
71  };
72  static constexpr libjmmcg::uint128_t mask=(~libjmmcg::uint128_t{})>>(converter::num_chars_to_mask);
73  converter cl(*this);
74  cl.conv&=mask;
75  assert(cl.isin==*this);
76  converter cr(i);
77  cr.conv&=mask;
78  assert(cr.isin==i);
79  return cl.conv<cr.conv;
80 }
81 
82 inline std::string
83 ISIN_t::to_string() const noexcept(false) {
84  return std::string{value.block.begin(), value.block.end()};
85 }
86 
87 constexpr inline std::size_t
88 ISIN_t::hash() const noexcept(true) {
89  std::uint64_t left_half{};
90  for (std::size_t i=0; i<value.block.max_size()/2; ++i) {
91  left_half|=(static_cast<std::uint64_t>(value.block[i])<<(i*8));
92  }
93  std::uint64_t right_half{};
94  for (std::size_t i=0; i<value.block.max_size()/2; ++i) {
95  right_half|=(static_cast<std::uint64_t>(value.block[i+value.block.max_size()/2])<<(i*8));
96  }
97  auto const hash_value=left_half^right_half;
98  assert(hash_value!=0);
99  if constexpr (sizeof(std::uint64_t)<=sizeof(std::size_t)) {
100  assert(hash_value<=std::numeric_limits<std::size_t>::max());
101  return static_cast<std::size_t>(hash_value);
102  } else {
103  assert(sizeof(std::size_t)==sizeof(std::uint64_t)/2);
104  union conv {
105  std::uint64_t i_;
106  std::size_t sz[2];
107 
108  explicit constexpr conv(std::uint64_t i) noexcept(true)
109  : i_(i) {}
110  };
111  const conv c(hash_value);
112  return c.sz[0]^c.sz[1];
113  }
114 }
115 
116 inline std::ostream &
117 operator<<(std::ostream &os, ISIN_t const &i) noexcept(false) {
118  os<<i.value.block;
119  return os;
120 }
121 
122 inline std::istream &
123 operator>>(std::istream &is, ISIN_t &i) noexcept(false) {
124  std::string tmp;
125  is>>tmp;
126  assert(tmp.size()<=sizeof(ISIN_t));
127  libjmmcg::memcpy_opt(reinterpret_cast<ISIN_t::block_t const &>(*tmp.data()), i.value.block);
128  return is;
129 }
130 
131 } } } }