@@ -6,30 +6,151 @@ namespace template_traits
66 namespace  problem 
77 {
88 const  unsigned  max_chunk = 100 ;
9-  //  
9+ 
10+  //  works for ascii only
1011 class  stream_buffer 
1112 {
1213 public: 
13-  stream_buffer (const  std::string& input) {
14-  buff = new  char [input.size ()];
15-  std::memcpy (buff, input.c_str (), input.size ());
14+  //  ...
15+  //  return the next character or EOF
16+  int  sgetc () {
17+  return  EOF;
1618 }
19+  };
1720
18-  ~stream_buffer ()
21+  //  works when unicode
22+  class  stream_buffer_unicode 
23+  {
24+  public: 
25+  //  ...
26+  //  return the next character or EOF
27+  wint_t  sgetc () {
28+  return  WEOF;
29+  }
30+  };
31+ 
32+ 
33+  void  demonstrate ()
34+  {
35+ #if  UNICODE
36+  stream_buffer_unicode buffer;
37+  //  get buffer and process
38+  wint_t  ch;
39+  while  ((ch = buffer.sgetc ()) != WEOF)
1940 {
20-  delete  buff;
41+  //  process buffer
42+  putwchar (ch);
2143 }
44+ #else 
45+  stream_buffer buffer;
46+  //  get buffer and process
47+  int  ch;
48+  while  ((ch = buffer.sgetc ()) != EOF)
49+  {
50+  //  process buffer
51+  putchar (ch);
52+  }
53+ #endif 
54+  }
55+ 
56+  } //  namespace problem
57+ 
58+  namespace  solution 
59+  {
60+  template  <typename  CharT>
61+  struct  char_traits  { };
62+  //  specialization for ascii chars
63+  template  <>
64+  struct  char_traits <char > {
65+  using  char_type = char ;
66+  using  int_type = int ;
67+  static  inline  int_type eof () { return  EOF; }
68+  };
69+  //  specialization for unicode chars
70+  template  <>
71+  struct  char_traits <wchar_t > {
72+  using  char_type = wchar_t ;
73+  using  int_type = wint_t ;
74+  static  inline  int_type eof () { return  WEOF; }
75+  };
2276
77+  //  now we can support different char representations by
78+  //  using trait helpers
79+  template  <typename  CharT>
80+  class  basic_stream_buffer 
81+  {
82+  public: 
83+  using  traits_type = char_traits<CharT>;
84+  using  int_type = traits_type::int_type;
2385 //  ...
24-  int  sgetc (); //  return the next character or EOF
25-  int  sgetn (char  *, int  N); //  get N characters from buffer
26-  private: 
27-  char  *buff;
86+  static  int_type eof () { return  traits_type::eof (); }
87+  //  return the next character or EOF
88+  int_type sgetc () {
89+  return  traits_type::eof ();
90+  }
2891 };
2992
30-  } //  namespace problem
93+ #if  UNICODE
94+  using  basic_stream = basic_stream_buffer<wchar_t >;
95+ #else 
96+  using  basic_stream = basic_stream_buffer<char >;
97+ #endif 
98+  void  demonstrate ()
99+  {
100+  basic_stream buffer;
101+  //  get buffer and process
102+  basic_stream::int_type ch;
103+  while  ((ch = buffer.sgetc ()) != basic_stream::eof ())
104+  {
105+  //  process buffer
106+  putchar (ch);
107+  }
108+  }
109+  } //  namespace solution
110+ 
111+  namespace  type_traits 
112+  {
113+ 
114+  template  <typename  Type>
115+  struct  is_integer  {
116+  static  const  bool  val = false ;
117+  };
118+ 
119+  template  <>
120+  struct  is_integer <int > {
121+  static  const  bool  val = true ;
122+  };
123+ 
124+  template  <>
125+  struct  is_integer <unsigned  int > {
126+  static  const  bool  val = true ;
127+  };
128+ /* 
129+ The simplest solution to compile-time assertions (Van Horn 1997), and one that works in C as well as in 
130+ C++, relies on the fact that a zero-length array is illegal. 
131+ */ 
132+ #define  STATIC_CHECK (expr ) { char  unnamed[(expr) ? 1  : 0 ]; }
133+ 
134+  template  <typename  T>
135+  void  will_work_for_only_integer_types (T a, T b)
136+  {
137+  STATIC_CHECK (is_integer<T>::val);
138+  }
139+ 
140+ #include  < type_traits> 
141+ 
142+  template  <typename  T, 
143+  typename  = std::enable_if_t <std::is_integral<T>::value>>
144+  T will_work_for_only_integer_types_cpp11 (T a, T b)
145+  {
146+  return  a + b;
147+  }
148+ 
149+ 
150+  } //  namespace type_traits
31151}
32152
33- ELEMENT_CODE (TemplateTraits) {
153+ ELEMENT_CODE (TemplateTraits)
154+ {
34155
35156}
0 commit comments