//********************************************************
// The following code example is taken from the book
//  C++23 - The Complete Guide
//  by Nicolai M. Josuttis (www.josuttis.com)
//  http://www.cppstd23.com
//
// The code is licensed under a
//  Creative Commons Attribution 4.0 International License
//  http://creativecommons.org/licenses/by/4.0/
//********************************************************


#include <iostream>
#include <string>
#include <sstream>
#include <expected>
#include <utility>  // for in_range<>()
#include <cctype>   // for isdigit()

// read next line (might have no data):
std::expected<std::string, std::string> readLine(std::istream& is)
{
  std::string row;
  if (std::getline(is, row)) {
    if (!row.empty()) {
      return row;
    }
    else {
      return std::unexpected("line is empty");  
    }
  }
  return std::unexpected("no line");
}

// convert string to int (might not be a valid int):
std::expected<int, std::string> asInt(const std::string& s)
{
  // is the string a valid int (at the beginning)?
  char first = s[0];
  if (first == '-') first = s[1];
  if (!std::isdigit(first)) {
    return std::unexpected("\"" + s + "\" is no valid int");
  }

  return std::stoi(s);
}

// square an int value:
long square(int val)
{
  return 1L * val * val;
}

void process(std::istream& strm)
{
  while (strm) {
    // read next line, convert to int and square:
    std::expected exp = readLine(strm).and_then(asInt).transform(square);
    if (exp) {
      std::cout << *exp << '\n';
    }
    else {
      std::cout << "ERROR: " << exp.error() << "\n";
    }
  }
}

int main()
{
  // simulate input stream:
  static std::stringstream sStrm{"7\n100000\nhi\n\n-11"};

  process(sStrm);
}

